2017-01-01 8 views
-1

Javaの繰り返しオブジェクトの割り当てのもパフォーマンスへの影響

Deque<Boolean> tail = new LinkedList<>(); 
    for (int i = 1; i <= n; i++) { 
     tail.addFirst(true); 
     tail.pollLast(); 
    } 

私の最初のguesは、GC時間だったが、それは3.5秒のうち100ミリ秒かかりのみ。 これの背後にある理由を見つける最も良い方法は何ですか?

+3

リンクリストでは、要素を追加するたびに新しいノードを割り当てる必要があります。配列または 'ArrayList'は、要素を保持するために一度に多数のスロットを割り当てるため、配列リストや配列リストはありません。割り当てに時間がかかります。 – ajb

+0

あなたの答えは多分ここにあります。 http:// stackoverflowを見てください。com/questions/1589813/when-to-use-a-list-in-java-as-in-java。 –

答えて

1

これの背後にある理由を特定するにはどうすればよいでしょうか?

多くの方法があります。

  1. は、適切なベンチマークにあなたの一例を回して、プロファイラを使用してそれを実行

    。それから、時間がどこで使われているのか見てみましょう。

  2. 呼び出しているLinkedListメソッドのソースコードを見てください。

  3. コードとLinkedListコードのJavacコンパイラによって生成されたバイトコードを調べます。

  4. コードとLinkedListコードについて、JITコンパイラによって生成されたネイティブコードを調べます。

(私はそれが特に予想外の何も表示されますことを疑うので、私は、これを自分で調査するためにあなたを残します。)


私の最初の推測では、GC時間だったが、それは100ミリ秒を取り出します3.5秒のみ。

ほとんどの場合、リンクリストノードオブジェクトの割り当てと初期化、およびリストメソッドのその他のオーバーヘッドが発生する可能性があります。

リストを作成するときにGCを実行する必要がある場合、GCのオーバーヘッドは、配列の大文字小文字の区別よりも少し大きい場合があります。しかし、実際に起こっていることは、GCが実際にコードローディング中に作成されたオブジェクトやJITコンパイル時に作成されたオブジェクトを再利用しているということです。リスト/アレイビルディングの間に生産された実際の回収可能ごみの量は、どちらの場合もである必要があります。

ベンチマーク手法が結果を歪める可能性もあります。たとえば、私はあなたのpollLast呼び出しがリストを構築することに関して何か有用なことをしていないことに注意します。別の問題は、JVMウォーミングアップ効果を許可していない可能性があることです。

一般に、表示される10倍の違いは、Javaリストと配列のパフォーマンスの「受け入れられた知恵」に相当します。 LinkedListの代わりにArrayListを使用した場合、特に、ArrayList容量の良好な見積もりを行った場合、パフォーマンスはベア配列に近くなります。

関連する問題