2017-01-23 5 views
5

removeLastを呼び出すのは非常に遅いです(77k要素をポップするには数分かかる)。 documentationはO(1)と言いますが、実装では単純に配列のサイズを減らすと思います。明らかではない:swift array removeLast非常に遅い

stack trace indicating <code>removeLast</code> calling memmove

なぜそれが呼んでいるremove(at: Int)

このREPRO場合は、(私はC++のstd::vectorパフォーマンスに慣れている)私は予想よりも遅いですが、私は自分のコードで見ているものとはまだのように遅くない:

var array = [ Int ]() 

for i in 0..<262144 { 
    array.append(i) 
} 

print ("done appending") // we get here immediately 

let n = array.count 
for _ in 0..<n { 
    array.removeLast() // popLast is also slow 
} 

print ("done") 

これは16秒かかります私のマシンで。同等のC++プログラムには0.002秒かかります。

+2

あなたはこれをテストする方法のコードを投稿することができますか? – Fogmeister

+0

配列は、コピー・オン・ライトする値の型です。だから、 'removeLast'に新しいコピーを作るのは意味があります。しかし、これは速くなければならないと思う人もいます。 –

+0

@Fogmeister私はすべてのコードをダンプすることなく、再プロ用のコードを抜き出しています。私が似たようなテストケースを書くと、速いです。微妙なことが起こっている。 – Taylor

答えて

4

問題はあなたがテストしている方法です。 いいえデバッグビルドのスピードテストは、少しでも意味があります。このため、は常にのプロファイルに設定する必要があります。リリースビルドを使用します。現実的な結果を得るには、機器の機器でプロファイルを作成します。他のすべては錯覚です。

リリースビルドではなく、デバッグビルドを行います。実際にはprintステートメントとすぐにの両方が表示されます。

結果(私のコンピュータ上で、デバイスではなく、私は私のポケットから携帯電話を取るのが面倒だったので)基準日以降の秒を表示:

starting 506917910.056674 
done appending 506917910.060245 
done 506917910.069827 
+0

確認することができます:即座に 'swift -O test.swift'が完了しました – Alexander

+0

愚かな私。私は使用可能なデバッグビルドに慣れています! – Taylor

+0

メモリ管理についても同じことが言えます。 SimulatorのDebugビルドでの素早いメモリ管理は大きな嘘です。 – matt