5

これが重複している場合はお詫びします - いくつか検索しましたが、必要なものが見つかりませんでした。

受信データの Play 2.0 Enumerator( と考えることができます) を(または類似の) に変換するアプリケーションのパフォーマンスが重要な部分があります。メソッドを使用しますが、問題は、それを行う最もパフォーマンスの高い方法は何かということです。(コードでは代わりに使用しますが、考え方は同じです。)StreamListfoldEnumeratorStreamEnumerator

val incoming: Stream[Int] = ???
val result: Seq[Int] = incoming.fold(Seq.empty)(_ + _)
val result2: Seq[Int] = incoming.fold(MutableList.empty(_ += _).toSeq

したがって、問題は本質的に、不変に繰り返し追加することは、可変またはパフォーマンスが重要なコードに繰り返し追加することとどのようにVector比較されるのでしょうか? 追加する必要があるという理由だけで(前に追加するのではなく)捨てました。しかし、ミュータブルなデータ構造は、パフォーマンスやガベージ コレクションの面で何かメリットがあるのでしょうか?MutableListListBufferListO(1)

4

1 に答える 1

19

を使用するのがおそらく最善ArrayBufferです。私のマシンでは、毎秒次の数の追加が得られます。

preallocated Array[Int]    -- 830M
resized (x2) Array[Int]    -- 263M
Vector.newBuilder + result -- 185M
mutable.ArrayBuffer        -- 125M
mutable.ListBuffer         -- 100M
mutable.MutableList        --  71M
immutable.List + reverse   --  68M
immutable.Vector           --   8M

常にintを格納しているわけではなく、余分なラッピングなしですべてのコレクションの良さを望んでいるので、ArrayBuffer一方の端に追加するだけでよい限り、最高のパフォーマンスを発揮するソリューションです。リストは双方向の追加をサポートし、比較可能です。Vector は比較すると恐ろしく遅いです。大量のデータ共有を利用するか、すべてを一度に作成できる場合にのみ使用してください (Vector.newBuilder結果を参照してください。これは素晴らしいことです。アクセス、反復、および作成のための優れたデータ構造です)常時更新ではなく、スペア更新)。

于 2012-12-27T18:09:14.357 に答える