【问题标题】:Big O of append in GolangGolang中追加的大O
【发布时间】:2013-06-24 07:26:06
【问题描述】:

Go 的内置 append 函数的复杂度是多少?使用+ 进行字符串连接怎么样?

我想通过附加两个不包括该元素的切片来从切片中删除一个元素,例如。 http://play.golang.org/p/RIR5fXq-Sf

nums := []int{0, 1, 2, 3, 4, 5, 6, 7}
fmt.Println(append(nums[:4], nums[5:]...))

=> [0 1 2 3 5 6 7]

http://golang.org/pkg/builtin/#append 表示如果目标有足够的容量,则该切片为resliced。我希望“重新切片”是一个恒定的时间操作。我也希望这同样适用于使用+ 的字符串连接。

【问题讨论】:

标签: go append complexity-theory slice


【解决方案1】:

这一切都取决于使用的实际实现,但我基于标准 Go 和 gccgo。

切片

Reslicing 意味着改变一个结构中的一个整数(一个切片是一个具有三个字段的结构:长度、容量和指向后备内存的指针)。

如果 slice 没有足够的容量,append 将需要分配新的内存并将旧的复制过来。对于具有 1024 个元素的切片,它将增加 1.25 倍。

字符串

由于字符串是不可变的,每个与+ 的字符串连接都会创建一个新字符串,这意味着复制旧字符串。因此,如果您在循环中执行 N 次,您将分配 N 个字符串并复制大约 N 次内存。

【讨论】:

  • 谢谢!将一片 uint8 传递给 string 函数怎么样?是O(1) 还是O(n)? (标准 Go 实现)
  • O(n)。切片是可变的,字符串不是 → 它必须复制数据。
  • 换句话说,将一个元素附加到一个切片是摊销 O(1)。
  • 这是官方记录的吗?
  • @Bryan 正如在这篇文章中指出的reddit.com/r/golang/comments/39w6e2/…,您可以在这里找到硬编码的这种行为golang.org/src/runtime/slice.go#L59
猜你喜欢
  • 2017-06-17
  • 1970-01-01
  • 2012-04-24
  • 1970-01-01
  • 2016-12-03
  • 2018-04-15
  • 2015-03-16
  • 2015-09-15
  • 2016-12-06
相关资源
最近更新 更多