go语言性能建议
原文链接 http://reborncodinglife.com/2016/04/07/go-performance-advice/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。
最近为了学习go语言,花了点时间翻译《the way to go》这本书相关章节:
详见:https://github.com/Unknwon/the-way-to-go_ZH_CN
在翻译过程中学习了一些go语言性能建议,特此总结分享,以后在使用go过程中尽量采用,以提升性能。
1 字符串
连接字符串效率最高是使用bytes.Buffer
,如下:
var buffer bytes.Buffer
for {
if s, ok := getNextString(); ok {
buffer.WriteString(s)
} else {
break
}
}
fmt.Print(buffer.String(), "\n")
这种实现方式比使用+=
要更节省内存和CPU,尤其是要串联的字符串数目特别多的时候。
2 通道
使用带缓存的通道可以很轻易成倍提高吞吐量,某些场景其性能可以提高至10倍甚至更多。通过调整通道的容量,甚至可以尝试着更进一步的优化其性能。即尽可能在需要分配大量内存时使用缓存。例如:
buf := 100
ch1 := make(chan string, buf)
3 使用指针类型作为方法的接受者
当定义一个方法时,使用指针类型作为方法的接受者,传递的是一个指针,如果接受者是一个值类型,传递的是一个值拷贝,会造成内存开销(此处和原书16.7小节有点矛盾,16.7小节建议尽量以值类型作为方法的接受者,详情参考原书16.7小节)。例如:
type TwoInts struct {
a int
b int
}
func (tn *TwoInts) AddThem() int {
return tn.a + tn.b
}
4 函数内部使用:=
声明变量
在函数内部尽可能的使用:=
去初始化声明一个变量,这是使用变量的首选形式,但是它只能被用在函数体内,而不可以用于全局变量的声明与赋值。使用操作符:=
可以高效地创建一个新的变量,称之为初始化声明。
5 切片
如果只想获取切片中某项值,不需要值的索引,尽可能的使用for range去遍历切片,这比必须查询切片中的每个元素要快一些。例如:
for ix, value := range arr {
…
}
6 映射
初始化映射时指定其容量,即尽可能在需要内存时使用缓存。节省内存分配的开销,提高效率。例如:map2 := make(map[string]float, 100)
7 参考
《the way to go》