2013-06-26 15 views
9

goの組み込みappendの複雑さは何ですか? +を使った文字列連結はどうですか?ゴランの追記の大きな部分

私はその要素を除いて2つのスライスを追加することでスライスから要素を削除したいと思います。 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であることを述べています。私は "reslicing"が一定の時間の操作であることを望んでいます。私は同じことが+を使用して文字列の連結にも適用されることを望んでいます。

+0

動作に関する一部の情報:http://criticalindirection.com/2016/02/17/slice-with-a-pinch-of-salt/ – user31986

答えて

19

これはすべて実際に使用されている実装に依存しますが、これは標準のGoとgccgoに基づいています。

スライス

Reslicing(スライスは、三つのフィールドを持つ構造体である:バッキングメモリに長さ、容量、およびポインタ)構造体の整数を変更することを意味します。

スライスの容量が不足している場合は、新しいメモリを割り当てて古いものをコピーする必要があります。 < 1024要素のスライスでは、容量が2倍になります。スライスの要素数が1024を超えると、係数は1.25倍に増加します。

ストリングス

文字列は不変ですので、+と各文字列の連結は、古いものをコピーすることを意味し、新しい文字列を作成します。だから、あなたがループでN回それをしているなら、あなたはN回の周りにN個の文字列を割り当て、メモリをコピーします。

+0

ありがとうございます! uint8のスライスを 'string'関数に渡すのはどうでしょうか?それは 'O(1)'か 'O(n)'ですか? (標準Go実装) – Kaleidoscope

+2

O(n)。スライスは変更可能であり、文字列はデータをコピーする必要はありません。 –

+6

つまり、スライスに要素を追加すると、O(1)が償却されます。 – newacct

関連する問題