先说结论,指针传参 性能要远远高于直接传递值。并不会因为指针导致内存逃逸到堆上。
原因很简单:函数内的变量创建和销毁需要大量的性能开支。
无论是否用协程 无论参数类型,无论数据在函数内怎么处理。
req,err=func(xxx)
的性能 也低于 func(&xxx,&req,&err)
用指针需要注意的是 1、函数内部修改值的时候数据的安全 2、如果有内存逃逸的情况会增加gc负担 会导致性能会下滑
测试代码 ,字符串拼接的因为牵扯到内存的重新分配所以性能差距更大。 不拼接只检查字符串长度,可以增加mianLoop采样次数 此时指针依旧是更快的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
| package main
import (
"log"
"time"
)
func main() {
var strLong string = "Sr5sLSyfjqUR8LBp0DHM6HfnYDLR09vmxwLNlM_fn7fa6Psm-4vWjEvooi6OsT5b8a_k7w-wOuGB2PHPUPMse2zj9YxYOyEDQejFDf_ESqe3ESDa_evh8rnZWF7j3jsYjB-BsCF1jWS41M2UI7UjDX_3QZGZ9EScMmMOZykAkWN8AJUbjsEbc_gofOmxjAabmSvKcHh1zhK3IQcomP3s5oBj2T32oV098jR3IqZsPkaAOcvr-LHSETaTmwKmjd-Qb00haPiuuTWxVqm0gPJ3nz-JzWTh8_9H8Jv9IMWbH0mh2T-KuzcHFGevPGqNM-5GdGo4iISCkx10Sekj1TDb1YHyS6G1A6MZCWHcjml5iQ0Ull-Wynp1EOqZHInbOl0h4JDEyFEk4UAGGr705_FwB_6R6WRJd1Ma6UFfP2HtbU0BsMoHLcTlhdsuURRdHY33KAJCD4pdduuGKeCqtRVLFa4furAjbsqnvivg44FIVyxDmxFSKf9SkgMJ3OiwpVn9bWTiuKlJu1ezb5L68JkNGcOEf94hC34XKCBI6uTA0pKZg6bTAru5ZknCa3-PeSmJAP7mznL3lLPinMIEhuoF0y09qGTVIIleM9wCsmZHa5Gdw8YndeVzlHKA9BBO5GMMuUFMBH4bbCj0onuiJ7vlYxO7PMQF-pEIk0TcZyjL__XqhAA07xg-L-xF4tfvHI-MBgJNrfjCPayIfYsjxtQ23V5uXhfoAeluzZNxPjr3f857VPxagTU4VgAUlZYC7qH0LqoKHsngAnEV38QIOFC4H3T3KOykT-Vf-z8xbZQ2u-0h2GAb4h1blmg9li9zmRXhoE88q9_H8PUP3d1CklPtP6Mqi0b2f3GPM9YqSAvEF-IfZ4nepn9dRmKg18Wnz8IC0_7gaOXX_C-OcSuR60Qk9WwRw0pyjig75VwY6ZFQ0MyuGM_1T8nIeIt84Ks272LWFHpIPt7s9uFcM0AtGbeg_SK4NkjRg6F1DrXKLqtFXZfszK19_WWvG2bEpsByvmjcuu_4Sye6OxBgpkyS1yxMsBQKCwoa4kaPtdXCxFHBLT6wLw4uS11Ym_Z5d36X035j6v5W9l9dst5hzsnUq1C2ZOLAuptiKkRTt-O-jzZTPGaJc-K79xtT8dyUn0CuRylRCbl1XFCSu2ZgEeebpJ8s-zEiNA3wZq9ZsEMQsNmD_433XUY4FAdQTFRAD-iQvFcUuKb2yhJ4zu1diw_pIstvrOZy04CNdxLtKswNYFN3CaiGVU-egu_r-Ao-SIUXgFi-G7ARsnNBpUKeL3NXjcStEa_b-ldZrzSZc2fTca_kH7CykR47q-x-pAVj9CxCMMZK10i1rCeHyMWqfWRFmKmztb9kW8xI0x7aUZwLosHs52ljg8dvwHyZQGEU2rYNehGvbvaz1M-Y1qaRZIym9w9M-qlmQc7ymnIjr3TKBDpq8UcoNT6wQj12l5TdcrtmzOWX"
//strLong = "1234567890abcdefghijklmnopqrstuvwxyz"
var strLong2 = strLong
log.Println("。。。", len(strLong2))
log.Println("字符长度", len(strLong))
var NumberOfprocesses = 100
var count int64 = 0
for mianLoop := 0; mianLoop < 1000; mianLoop++ {
//var wg sync.WaitGroup
startTime := time.Now().UnixNano()
for i := 0; i < NumberOfprocesses; i++ {
//wg.Add(1)
//go func(varStr string) {
func(varStr string) {
//defer wg.Done()
//varStr = varStr + strLong2
if len(varStr) > i {
return
}
}(strLong)
}
//wg.Wait()
endTime := time.Now().UnixNano()
timeDiff1 := endTime - startTime
//log.Println("耗时", timeDiff1, "纳秒")
startTime = time.Now().UnixNano()
for i2 := 0; i2 < NumberOfprocesses; i2++ {
//wg.Add(1)
//go func(varStr *string) {
func(varStr *string) {
//defer wg.Done()
//*varStr = strLong2 + strLong2
if len(*varStr) > i2 {
return
}
}(&strLong)
}
//wg.Wait()
endTime = time.Now().UnixNano()
timeDiff2 := endTime - startTime
//log.Println("耗时", timeDiff2, "纳秒")
//log.Println("差值", timeDiff1-timeDiff2, "纳秒")
count = count + (timeDiff1 - timeDiff2)
}
log.Println("差值", count, "纳秒")
}
|
检查内存
1
| go build -gcflags '-m' ./
|