リストが一度に1つの要素で作成され、後で一度に1つの要素が読み取られるシナリオで、(Javaでの)最速のリスト実装は何ですか?読み取りはイテレータで実行され、リストは破棄されます。
getのBigO表記はO(1)、addはArrayListの場合はO(1)、LinkedListの場合)はO(n) getの場合、O(1) addの場合です。イテレータは同じBigO表記で動作しますか?
各リストの最大サイズを前もって知っているかどうかに大きく依存します。
その場合は、ArrayList
を使用してください。それは確かに速くなります。
それ以外の場合は、おそらくプロファイルする必要があります。 ArrayList
へのアクセスはO(1)ですが、動的なサイズ変更のため、作成はそれほど簡単ではありません。
考慮すべきもう1つのポイントは、時空のトレードオフが明確ではないということです。各Javaオブジェクトにはかなりのオーバーヘッドがあります。ArrayList
は余ったスロットでいくらかのスペースを浪費する可能性がありますが、各スロットはわずか4バイト(または64ビットJVMでは8)です。 LinkedList
はおそらく約50バイト(64ビットJVMではおそらく100バイト)です。したがって、ArrayList
が実際に推定スペースアドバンテージを獲得するには、LinkedList
にかなりの数の無駄なスロットが必要です。参照の局所性も要因です。そこでもArrayList
が望ましいです。
実際には、私はほとんどの場合ArrayList
を使用します。
最初の考え:
もちろん、他の誰もが言及しているように、パフォーマンステストを行い、新しいソリューションが改善であることを証明します。
リンクリストの反復は、要素ごとにO(1)です。
各オプションのBigOランタイムは同じです。おそらく、メモリの局所性が優れているため、ArrayListの方が高速になりますが、確実に知るためには、ArrayListを測定する必要があります。コードが最も明確になるものを選択してください。
LinkedList
のインスタンスを反復処理することは、単純に実行するとO(n ^ 2)になる可能性があることに注意してください。具体的には:
List<Object> list = new LinkedList<Object>();
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
これは、反復ごとにリストをi
twiceまでトラバースする必要があるため、効率の点で絶対に恐ろしいものです。 LinkedList
を使用する場合は、必ずIterator
またはJava 5の拡張for
-loop:
for (Object o : list) {
// ...
}
上記のコードはO(n)です。これは、リストがステートフルにインプレースでトラバースされるためです。
上記の煩わしさをすべて回避するには、ArrayList
を使用します。これは(特にスペース効率の点で)常に最良の選択であるとは限りませんが、通常は安全な方法です。
ほぼ確実にArrayListが必要です。加算と読み取りはどちらも「償却定数時間」です(つまり、ドキュメントで指定されているO(1))(リストのサイズを大きくする必要がある場合でも、これは当てはまります。 http://Java.Sun.com/j2se/1.5.0/docs/api/Java/util/ArrayList.html を参照してください。保存するオブジェクトの数がおおよそわかっている場合そうすれば、ArrayListのサイズの増加さえも排除されます。
リンクリストの最後に追加されるのはO(1)ですが、定数乗数はArrayListよりも大きくなります(通常は毎回ノードオブジェクトを作成するため)。イテレータを使用している場合、読み取りはArrayListと実質的に同じです。
正当な理由がない限り、常に可能な限り単純な構造を使用することをお勧めします。ここではそのような理由はありません。
ArrayListのドキュメントからの正確な引用は、次のとおりです。「追加操作は償却された定数時間で実行されます。つまり、n個の要素を追加するにはO(n)時間が必要です。他のすべての操作は線形で実行されます。時間(大まかに言えば)。定数係数は、LinkedList実装の場合と比較して低くなっています。」
GlueList と呼ばれる新しいList実装があります。これは、すべての従来のList実装よりも高速です。
ベンチマークすることをお勧めします。 APIを読むことは1つのことですが、実際に試してみるまではアカデミックです。
テストはかなり簡単である必要があります。意味のある操作を行うようにしてください。そうしないと、ホットスポットがあなたを賢くし、すべてをNO-OPに最適化します:)