2016-05-25 5 views
2

データベースにマージする準備の整った3483オブジェクトのArrayListがあります。 ラムダ式を使用すると、85122ミリ秒かかります。 しかし、for(Obj o : list)にかかる時間はわずか25msです。なぜJava8が3404時間以上かかるのでしょうか?Java 8 forEachループ時間がかかるのはなぜですか?

List<CIBSubjectData> list1 = ..... 

list1.forEach(data -> 
    merge(data) 
); 

for (CIBSubjectData data : list1) { 
    merge(data); 
} 
+1

パラレルストリームを試しました:list1.parallelStream()。forEach(data - > merge(data))? –

+1

あなたの答えはint [この質問](http://stackoverflow.com/questions/16635398/java-8-iterable-foreach-vs-foreach-loop)です。 – SomeJavaGuy

+2

ここでは、より多くの文脈やコードが必要になると思います。 'forEach' +ラムダはもっと長い時間がかかりますが、一般的なケースでは*ずっと長くなりません。私はちょうど些細なチェックをしました(これは信頼できません(http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java)) ' LinkedList'には400kのエントリがあり、forEachには40msがかかりました。強化された 'for 'の外観は5msです。 –

答えて

3

私は適切なマイクロベンチマーク設定を使用していません。 bytecode instrumentation frameworkランタイムでラムダバイトコードを生成するために使用されるASM)+ lambda execution timeのウォームアップをexecution time of the loopと比較しています。

performance-difference-between-java-8-lambdas-and-anonymous-inner-classesとリンクされたドキュメントのこの回答を確認してください。リンクされたドキュメントには、フードの処理に関する深い洞察があります。

edit上記を示す小さなスニペットを提供してください。

public class Warmup { 
    static int dummy; 

    static void merge(String s) { 
     dummy += s.length(); 
     dummy++; 
     dummy -= s.length(); 
    } 

    public static void main(String[] args) throws IOException { 
     List<String> list1 = new ArrayList<>(); 
     Random rand = new Random(1); 

     for (int i = 0; i < 100_000; i++) { 
      list1.add(Long.toString(rand.nextLong())); 
     } 

     // this will boostrap the bytecode instrumentation 
     // Stream.of("foo".toCharArray()).forEach(System.out::println); 
     long start = System.nanoTime(); 
     list1.forEach(data -> merge(data)); 

     long end = System.nanoTime(); 
     System.out.printf("duration: %d%n", end - start); 
     System.out.println(dummy); 
    } 
} 

あなたがコードを実行した場合、それが掲載されたとして、あなたが最初のバイトコードのフレームワークを使用するしかないラインStream.of(...を(コメントを解除した場合、私のマシン上に印刷された期間が

duration: 71694425 

です時間)は、印刷された持続時間は

duration: 7516086 

です。これは、最初の実行の約10%です。

注記明示的であること。上記のようなベンチマークを使用しないでください。このような要件については、jmhをご覧ください。

+1

OPレポート "85122 ms";それは1分半です。私はこの「マイクロベンチマーキング」と呼んでいないでしょうし、ウォームアップが原因であるとは思わないでしょう。 –

+1

@tobias_k私は同意します。しかし、(Obj:list)はたった25msしかかかりません。だから彼は確かにマイクロベンチマークをしたいと思っています。さもなければ、ループにはかなりの時間がかかります。ラムダがもっと長い時間を要するという点について。我々はOPからより多くの情報を必要とする。 – SubOptimal

関連する問題