交换指针:相当于"std::unique_ptr::swap"



我不知道如何将C++std::unique_ptr::swap翻译成Go。

我正在使用std::unique_ptr<T、 删除程序>:C++中的交换:

std::unique_ptr<bool[]> maskA{new bool[num]};
std::unique_ptr<bool[]> maskB{new bool[num]};
// ...
maskA.swap(maskB); // Swap operation

如果我只是在Go中使用一个简单的maskA, maskB = maskB, maskA,我会错过什么吗?

maskA := make([]bool, num)
maskB := make([]bool, num)
// ...
maskA, maskB = maskB, maskA

此交换是否具有相同的功能?

简短答案:

这在功能上是等效的,但实际的性能影响是不同的。使用*[]bool表示最接近的等价物。

属性:

带有交换的分配具有以下属性:

  • maskAmaskB的值将被交换
  • 因为这些是切片,所以布尔的底层数组是而不是复制
  • 由于编译器的优化,切片描述符也可能不会被复制

由于切片的构建方式,最后两点很重要:它们是指向底层数组的小描述符。有关更多详细信息,请参阅切片内部。

C++和Go之间的区别:

在C++中,unique_ptr<foo>始终包含*foo,而交换仅涉及交换地址,这具有可预测的性能影响。

在Go中,类型是您给定的任何类型,编译器将复制值。工作量取决于类型:

  • 如果这些是大的(例如:arrays:[1000]bool(,可能会变得昂贵
  • 如果它们是您现在拥有的切片(例如:[]bool(,则会复制切片描述符
  • 如果它们是指针(例如:*[]bool(,这将与C相同++

因此,为了保证与C++代码等效,您应该使用指向布尔切片的指针(*[]bool(作为Go类型。

Go优化:

Go编译器将尝试优化掉变量交换。

这里有一个微不足道的例子:

func main() {
a := make([]bool, 0)
b := make([]bool, 0)
fmt.Println(a, b)
a, b = b, a
fmt.Println(a, b)
}

我们可以使用GOSSAFUNC=main go build .在编译过程中转储优化步骤

查看生成的ssa.html文件,我们可以看到a, b = b, a行被完全删除,下面的代码被更改为类似fmt.Println(b, a)的代码。

当这种情况发生时,交换只是编码的精细性,没有性能影响,但情况并非总是如此(编译器优化非常专业,有些情况下它无法做到这一点。例如:交换两个结构字段成员无法优化(。

不平等比较:

将两者进行比较有点奇怪。C++中的一个更接近的等价物是要交换的两个普通变量(无论是否为指针(。unique_ptr的主要目标是简化对象所有权,并在unique_ptr超出范围时删除底层对象。

Go没有unique_ptr的等价物,主要是因为它不需要,所有内存都是垃圾收集的。

相关内容

  • 没有找到相关文章

最新更新