gpt4 book ai didi

pointers - 清除截断指针的更快或更慢的方法?

转载 作者:行者123 更新时间:2023-12-01 20:26:26 27 4
gpt4 key购买 nike

在我最近阅读的truncate实现中,作者使用以下方法清除截断的项目:

var nilItems    = make(items, 16)

func (s *items) truncate(index int) {
var toClear items
*s, toClear = (*s)[:index], (*s)[index:]
for len(toClear) > 0 {
toClear = toClear[copy(toClear, nilItems):]
}
}

当我需要清除不需要的项目时,我只需遍历 slice 并将项目逐一设置为 nil

我已经设置了一个简单的 benchmark,看来 for循环的方式更快。

我想知道用 copy进行批量清除有什么好处。

最佳答案

正如@MartinGallagher所提到的,编译器可以识别并优化您的循环,而copy()版本的作用“太多了”,并且没有优化。

如果更改示例以填充非nil指针值,则会发现循环版本落后。也不要在基准测试循环内分配(make()),在外部进行分配,并使用b.ResetTimer()排除该时间。

您还有一个非常小的 slice ,如果您增加其大小,则差异将更加明显:

var x = new(int)

func BenchmarkSetNilOneByOne(b *testing.B) {
nums := make([]*int, 12800)
b.ResetTimer()
for i := 0; i < b.N; i++ {
for i := range nums {
nums[i] = x
}
}
}

func BenchmarkSetNilInBulk(b *testing.B) {
nils := make([]*int, 128)
for i := range nils {
nils[i] = x
}

orig := make([]*int, 12800)
var nums []*int
b.ResetTimer()
for i := 0; i < b.N; i++ {
nums = orig
for len(nums) > 0 {
nums = nums[copy(nums, nils):]
}
}
}

基准结果:
BenchmarkSetNilOneByOne-4          96571         10626 ns/op
BenchmarkSetNilInBulk-4 266690 4023 ns/op

还要注意,您的“批量”版本还会多次将 slice header 分配给 nums。有一种更快的方法来填充 slice :您不需要额外的“nils” slice ,只需开始填充 slice ,就可以将已经填充的部分复制到未填充的部分。这也不需要更改/重新分配给 nums slice头。参见 Is there analog of memset in go?

关于pointers - 清除截断指针的更快或更慢的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61869098/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com