常用数据结构
1.反射虽好,切莫贪杯
标准库 reflect 为 Go 语言提供了运行时动态获取对象的类型和值以及动态创建对象的能力。反射可以帮助抽象和简化代码,提高开发效率。
Go 语言标准库以及很多开源软件中都使用了 Go 语言的反射能力,例如用于序列化和反序列化的 json、ORM 框架 gorm、xorm 等。
1.1 优先使用 strconv 而不是 fmt
基本数据类型与字符串之间的转换,优先使用 strconv 而不是 fmt,因为前者性能更佳。
// Bad
for i := 0; i < b.N; i++ {
s := fmt.Sprint(rand.Int())
}
BenchmarkFmtSprint-4 143 ns/op 2 allocs/op
// Good
for i := 0; i < b.N; i++ {
s := strconv.Itoa(rand.Int())
}
BenchmarkStrconv-4 64.2 ns/op 1 allocs/op
为什么性能上会有两倍多的差距,因为 fmt 实现上利用反射来达到范型的效果,在运行时进行类型的动态判断,所以带来了一定的性能损耗。
1.2 少量的重复不比反射差
有时,我们需要一些工具函数。比如从 uint64 切片过滤掉指定的元素。
利用反射,我们可以实现一个类型泛化支持扩展的切片过滤函数。
// Bad
for i := 0; i < b.N; i++ {
s := fmt.Sprint(rand.Int())
}
BenchmarkFmtSprint-4 143 ns/op