1 回答
TA贡献1851条经验 获得超5个赞
正如@Adrian 指出的那样,很难想出一个始终指向正确切片并且与reflect.Swapper. 因为reflect.Swapper根据仅在包中的某些私有字段中可用的某些信息来选择可能的最快实现。
一个明显的优化机会是避免不必要地创建 new Swappers。
正如@Adrian 所建议的,我可以设置h.swapper为并且只有在确实被调用nil时才创建一个新的。Swap
我们可以通过检查底层数组的地址是否更改来使其更快。记住,新数组只有在 slice 没有足够空间时才会分配,大多数时候底层数组的地址应该是相同的,我们不需要创建新的交换函数。
通过上面的两个优化,代码将变为:
func (h *sliceHeap) Swap(i, j int) {
if i == j {
return
}
if h.swapper == nil {
h.swapper = reflect.Swapper(h.slice.Elem().Interface())
}
h.swapper(i, j)
}
func (h *sliceHeap) Push(x interface{}) {
e := h.slice.Elem()
slicePtr := e.Pointer()
e.Set(reflect.Append(e, reflect.ValueOf(x)))
// If the pointer to the first element of the slice changes, we need a new Swapper
if e.Pointer() != slicePtr {
h.swapper = nil
}
}
- 1 回答
- 0 关注
- 87 浏览
添加回答
举报