之前看过一篇文章,对比分析了三种字符串拼接的性能,链接在这里
我正在玩的一个游戏就是千里码之嘻刷刷,要求一些特定的字符尾随一些数字,最终要md5的结果前6位均为0。
用php实现了下遍历,I7 8核跑很久都跑不出来一个结果。。。所以,主意打到了稍稍懂点儿的Go上。在对性能有要求的程序上,追求卓越的性能是没有错的。所以,基于开头提到的那篇文章,我自己又做了一些测试。
由于我的场景比较特殊,是知道字符串只需要拼接一次的。所以,在数据类型上,就可以直接使用[2]string
了。
详细测试代码如下:
package main import ( "bytes" "strconv" "strings" ) func main() { } func a(s []string, i int) string { s = append(s, strconv.Itoa(i)) return strings.Join(s, "") } func b(s string, i int) string { ss := [2]string{s, strconv.Itoa(i)} return strings.Join(ss[:], "") } func c(s [2]string, i int) string { s[1] = strconv.Itoa(i) return strings.Join(s[:], "") } func d(s string, i int) string { buf := bytes.NewBufferString(s) buf.WriteString(strconv.Itoa(i)) return buf.String() }
Benchmark代码
package main import ( "testing" ) func Benchmark_a(t *testing.B) { s := []string{"20160122wclssdn1"} for i := 0; i < t.N; i++ { a(s, i) } } func Benchmark_b(t *testing.B) { s := "20160122wclssdn1" for i := 0; i < t.N; i++ { b(s, i) } } func Benchmark_c(t *testing.B) { s := [2]string{"20160122wclssdn1", ""} for i := 0; i < t.N; i++ { c(s, i) } } func Benchmark_d(t *testing.B) { s := "20160122wclssdn1" for i := 0; i < t.N; i++ { d(s, i) } }
Benchmark结果如下:
PASS
Benchmark_a-8 5000000 394 ns/op
Benchmark_b-8 10000000 231 ns/op
Benchmark_c-8 10000000 232 ns/op
Benchmark_d-8 3000000 527 ns/op
ok 9.810s
结果也不是一成不变的,有的时候b c的值是一样的。。。很明显,每次调用b都会新建一个[2]string,竟然跟每次不需要新建[2]string的c函数性能一样。。。