在指针上定义订单的最有效和最便携的方法是什么?

时间:2018-02-14 13:34:50

标签: go unsafe-pointers

我有一个包含指向值的指针。在我的程序的性能关键部分,我正在添加或删除此切片中的值。目前,插入一个值只是appendO(1)复杂度),并且删除包括在切片中搜索相应的指针值,从0到n-1,直到找到指针( O(n))。为了提高性能,我想在切片中对值进行排序,以便可以使用二分法进行搜索(所以O(log(n))。

但是如何比较指针值呢?在go中禁止指针算术,因此AFAIK比较指针值p1p2我必须使用unsafe包并执行类似

的操作
uintptr(unsafe.Pointer(p1)) < uintptr(unsafe.Pointer(p2))

现在,我不习惯使用unsafe,至少因为它的名字。那么,这种方法是否正确?它是便携式的吗?是否存在潜在的陷阱?有没有更好的方法来定义指针值的顺序?我知道我可以使用地图,但地图很慢。

1 个答案:

答案 0 :(得分:3)

正如其他人所说,不要这样做。对于在Go中使用指针算法而言,性能不是很重要。

指针具有可比性,Spec: Comparison operators:

  

指针值具有可比性。如果两个指针值指向同一个变量或两者的值都为nil,则它们相等。不同zero-size变量的指针可能相等也可能不相等。

只需使用指针作为键的地图。就那么简单。是的,索引映射比索引切片要慢,但是如果您想要对切片进行排序并且想要在其中执行二进制搜索,那么性能差距就会缩小,因为(哈希)映射实现提供了您O(1)查找二进制搜索时只有O(log n)。在大数据集的情况下,地图甚至可能比在切片中搜索更快。

如果您预计地图中会有大量指针,那么预先分配一个大make()的大指针,传递估计的大小,直到您的地图超过此大小,不会发生重新分配。

m := make(map[*mytype]struct{}, 1<<20) // Allocate map for 1 million entries