写了一个程序,需要不停处理输入。由于输入的长度绝对不会超过 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
当然,考虑到楼主是个渣的实际情况,或许是楼主把事情搞错了,于是来求教下解决办法。
如果真的实在没有办法让copy
变快,那么有没有其他办法可以让楼主欢快的直接修改buffer
里的大段数据呢?这个需求表述起来应该就像:
buffer[i:i+1024] = newInput[:1024]
// 那么楼主,为什么你不用for
呢:因为更慢啊亲
// 那么楼主,你可以建个 0 Len , N Cap 的 Buffer 来append
啊:但是这样也没快多少啊而且之后还需要 reset
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.