List li = new LinkedList();
for (int i = 0; i < 100; i++) {
li.add(i);
}
long start1 = System.nanoTime();
li.get(57);
long end1 = System.nanoTime();
long diff1 = end1-start1;
System.out.println("Time taken by LinkedList = "+diff1);
List al = new ArrayList();
for (int i = 0; i < 100; i++) {
al.add(i);
}
両方のリストでこれまでに実行した操作で、所要時間を出力すると、ArrayListは常にLinkedListよりも高速に実行されます。誰かが、所要時間の点でどちらが優れているかを説明できますか?また、コードに問題がある場合もお知らせください。ありがとう!
多くの挿入とそれほど頻繁ではない検索を実行する必要がある場合は、LinkedList
を使用します。挿入よりも多くのルックアップを実行する場合は、ArrayList
を使用します。
その理由は次のとおりです-ArrayList
は、初期容量を持つアレイによってサポートされています。したがって、リストに項目を挿入し続ける場合、ある時点で、配列容量を再調整して、新しく挿入された項目に対応する必要があります。また、インデックス固有の挿入を実行する場合は、既存の項目をシフトする必要がある場合もあります。一方、LinkedList
はリンクされたリストに基づいており、アイテムの作成は常に一定の時間で実行されます。アイテムを作成してリストの最後に割り当てます。ここでは再調整は行われません。
ArrayList
からアイテムをフェッチする場合、バッキング配列に一定の時間で簡単にインデックスを付けることができるため、常に一定の時間がかかります。ただし、LinkedList
からアイテムをフェッチすると、リンクされたリスト全体をトラバースしてアイテムノードを見つける場合があります。その結果、この場合はArrayList
よりもパフォーマンスが低下します。
上記の説明から、実行する挿入が多い場合、LinkedList
は常にArrayList
よりもパフォーマンスが優れていることがわかります。後者は内部のサイズ変更コスト挿入に関連付けられますが、前者はそうではありません。一方、挿入や検索が頻繁に行われない場合、ArrayList
は常にLinkedList
よりもパフォーマンスが高くなります。後者の場合、リンクされたリスト構造全体を走査して目的のアイテムを見つける必要があるためです。前者は、一定の時間で配列のインデックスを使用してアイテムをすばやく見つけることができます。
上記のすべての影響は目に見え、多くのアイテム(たとえば、数千のアイテム)を処理しているときにアプリケーションのパフォーマンスに影響を与えます。アイテムが少ない場合、パフォーマンスの違いはあまり目立ちません。
さて、あなたのコードについて、あなたはそれに関していくつかの深刻な問題を抱えています。手始めに、生の型を使用していますが、ジェネリックが提供する必要がある型の安全性をすべて失うため、これは悪いことです。新しいコードを作成する場合は、常にジェネリックバージョンのコレクションAPIを使用する必要があります。したがって、次のようにコードを変更します-
List<Integer> li = new LinkedList<Integer>();
for (int i = 0; i < 100; i++) {
li.add(i);
}
long start1 = System.nanoTime();
li.get(57);
long end1 = System.nanoTime();
long diff1 = end1 - start1;
System.out.println("Time taken by LinkedList = "+diff1);
List<Integer> al = new ArrayList<Integer>();
for (int i = 0; i < 100; i++) {
al.add(i);
}
Effective Java、を参照してください23:新しいコードで生の型を使用しないでください詳細な説明については。
[〜#〜]編集[〜#〜]
コメントの説明から、リストの中央またはランダムな位置に要素を挿入する必要がある場合、パフォーマンスの点でArrayList
がLinkedList
よりも優れていることは明らかです。 、前者はmemcpy
を使用して非常に高速な要素をシフトし、後者は新しい要素を適切に挿入するために目的のインデックスまでトラバースする必要があるため、低速です。したがって、ランダム挿入の場合、ArrayList
もLinkedList
よりも優れています。 LinkedList
がArrayList
よりもパフォーマンスが優れているのは、リストの最後にのみ挿入し、これらの挿入が多数ある場合のみです。
配列リストは、読み取りの点で常にリンクリストよりも高速です。 ArrayListは基本的に配列の実装であり、配列に割り当てられたメモリはシーケンシャルなので、読み取りが高速になります。ただし、リスト間の挿入または削除が必要なリストを使用する場合は、リンクリストの方が高速です。ノード間のリンクを追加する必要があるためです。これらの2つの場合、配列リストは遅くなります。使用方法は次のとおりです。
ArrayList-リスト間の読み込み操作、挿入、削除が高速になります。リンクリスト-配列リストと比較して読み取り操作が遅いが、リスト間の挿入、削除が高速。
ArrayList
は配列によってサポートされ、LinkedList
によってサポートされるノードは参照にリンクされます。
したがって、ArrayList
に対する操作は、配列に対する実際の評価操作です。追加操作は一定の償却時間で実行されます。つまり、n個の要素を追加するにはO(n)
時間を必要とします。他のすべての操作は線形時間(大まかに言えば)で実行されます。定数係数は、LinkedList
実装の定数係数に比べて低くなっています。
LinkedList
では、すべての操作は二重にリンクされたリストで期待されるように実行されます。リストにインデックスを付ける操作は、指定されたインデックスに近い方から、リストの最初または最後からトラバースします。
ドキュメントの詳細を読む-
LinkedList
は、各要素を追加するときに新しいノードを作成しますが、配列リストにはありません。
初期サイズがわかっている場合は、作成中にArrayList
に渡して、new ArrayList(100)
のような配列の再構築を回避します。