写了一个程序,需要不停处理输入。由于输入的长度绝对不会超过 N 且这段数据不需要考虑并发,聪明伶俐的楼主为了复用 Buffer ,决定用make([]byte, N)申请一段大[]byte,然后修改其中的内容。
然后,为了一次能一次修改大段内容,用到了copy。但是测试一下,发现copy在从src复制大段数据的时候,速度真太慢了。代码:
package main
import (
"testing"
)
func BenchmarkCopy(b *testing.B) {
data := make([]byte, 4096)
replace := make([]byte, 4050)
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
copy(data[2:], replace)
}
}
在我的机器上测试的结果:
#Go 1.7
[rain@localhost golang_copy_test]$ go test -bench . -cpuprofile cpu.out
testing: warning: no tests to run
BenchmarkCopy-2 1000000 1990 ns/op 0 B/op 0 allocs/op
PASS
ok _/home/rain/Develpment/Meta/golang_copy_test 2.016s
复制一段数据需要 1990 纳秒简直握草。 pprof 的结果显示时间大都消耗在了runtime.memmove上。
换了台机器,结果是这样:
# Go 1.6
BenchmarkCopy-8 5000000 256 ns/op 0 B/op 0 allocs/op
ok _/home/ubuntu/workspace/go_tests/copy_test 1.552s
但, 256 纳秒也不是很快啊。
况且,累积效应之后,在楼主真正的代码里,那速度啪啪噗的看起来是这样:
BenchmarkWriter-2 1000000 12745 ns/op 0 B/op 0 allocs/op
PASS
(就是它的错,箭头 men 坚决的说到)
当然,考虑到楼主是个渣的实际情况,或许是楼主把事情搞错了,于是来求教下解决办法。
如果真的实在没有办法让copy变快,那么有没有其他办法可以让楼主欢快的直接修改buffer里的大段数据呢?这个需求表述起来应该就像:
buffer[i:i+1024] = newInput[:1024]
// 那么楼主,为什么你不用for呢:因为更慢啊亲
// 那么楼主,你可以建个 0 Len , N Cap 的 Buffer 来append啊:但是这样也没快多少啊而且之后还需要 reset