带有循环的最简单的解决方案如下所示:
func memsetLoop(a []int, v int) { for i := range a { a[i] = v }}memset标准库中没有支持,但是我们可以使用
copy()高度优化的内置函数。
反复 copy()
我们可以手动设置第一个元素,然后使用
copy();开始将已设置的部分复制到未设置的部分。每次已经设置的部分越来越大(两倍),因此迭代次数为
log(n):
func memsetRepeat(a []int, v int) { if len(a) == 0 { return } a[0] = v for bp := 1; bp < len(a); bp *= 2 { copy(a[bp:], a[:bp]) }}此解决方案的灵感来自的实现
bytes.Repeat()。如果只想创建一个
[]byte填充相同值的新值,则可以使用该
bytes.Repeat()函数。您不能将它用于现有的切片或其他切片
[]byte,因为您可以使用呈现的切片
memsetRepeat()。
如果是小片,
memsetRepeat()可能会慢一些
memsetLoop()(但如果是小片,这并不重要,它将立即运行)。
由于使用fast
copy(),
memsetRepeat()如果元素数量增加,将会更快。
对这两个解决方案进行基准测试:
var a = make([]int, 1000) // Size will varyfunc BenchmarkLoop(b *testing.B) { for i := 0; i < b.N; i++ { memsetLoop(a, 10) }}func BenchmarkRepeat(b *testing.B) { for i := 0; i < b.N; i++ { memsetRepeat(a, 11) }}基准结果
100个元素: 快约1.15倍
BenchmarkLoop 20000000 81.6 ns/opBenchmarkRepeat 20000000 71.0 ns/op
1,000个元素: 快约2.5倍
BenchmarkLoop 2000000 706 ns/opBenchmarkRepeat 5000000 279 ns/op
10,000个元素: 快2倍
BenchmarkLoop 200000 7029 ns/opBenchmarkRepeat 500000 3544 ns/op
100,000个元素: 快约1.5倍
BenchmarkLoop 20000 70671 ns/opBenchmarkRepeat 30000 45213 ns/op
最高的性能提升约为3800-4000个元素, 速度提高了约3.2倍 。



