Большой О-аппенд в Голанге

В чем сложность встроенной функции append Go? Как насчет конкатенации строк с использованием +?

Я хотел бы удалить элемент из фрагмента, добавив два фрагмента, исключая этот элемент, например. 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. Я надеюсь, что "изменение" - это операция с постоянным временем. Я также надеюсь, что то же самое относится и к конкатенации строк с использованием +.

Ответ 1

Все это зависит от используемой фактической реализации, но я основываю это на стандартном Go, а также на gccgo.

Ломтики

Reslicing означает изменение целочисленного числа в структуре (срез представляет собой структуру с тремя полями: длина, емкость и указатель на резервную память).

Если срез не имеет достаточной емкости, append должен будет выделить новую память и скопировать старый. Для срезов с < 1024 элементами он удваивает емкость, для срезов s > 1024 элементами он увеличит его в 1,25 раза.

Строка

Поскольку строки неизменяемы, каждая конкатенация строк с помощью + создаст новую строку, что означает копирование старого. Поэтому, если вы делаете это N раз в цикле, вы будете выделять N строк и копировать память примерно в N раз.