2013-02-28 6 views
25

Java 7の一般的な経験から、Java 6よりも速いことがわかりました。しかし、私はこれが必ずしもそうであるとは思わないほど十分な情報に慣れてきました。パフォーマンスの問題を引き起こすJava 6と7の違いは何ですか?

情報の最初のビットは、Minecraft Snooperのデータから得られます。hereです。私の意図は、そのデータを見て、Minecraftを起動するために使用されたさまざまなスイッチの影響を調べることでした。たとえば、-Xmx4096mを使用してパフォーマンスにマイナスの影響があったかどうかを知りたかったのです。私がそこに行く前に、使用されている別のバージョンのJavaを見ていました。 1.5から1.8を使用している開発者まですべてを網羅しています。一般に、Javaバージョンを増やすと、fpsのパフォーマンスが向上します。 1.6のさまざまなバージョンでは、この徐々にトレンドアップしています。私は正直なところ、まだ野生のJavaの多くの異なるバージョンを見ることを期待していませんでしたが、私は人々がそれらのように更新プログラムを実行しないと思います。

1.6以降のバージョンでは、一番高いピークが表示されます。 1.7は、1.6の後のバージョンよりも平均で約10fpsを実行しますが、1.6の初期のバージョンよりもまだ高いです。私自身のシステムのサンプルでは、​​違いを見るのはほとんど不可能ですが、もっと広いサンプルを見ると明らかです。

誰かがJava用の魔法のスイッチを見つけた可能性をコントロールするには、スイッチが通過していないデータだけを見てください。そうすれば、さまざまなフラグを調べ始める前に合理的なコントロールができます。

私が見ていたことのほとんどは、誰かが私と共有していないMagic Java 6でもかまいませんので、私はそれを解雇しました。

今私は別のAPIで処理するためにInputStreamの配列を渡す必要がある別のプロジェクトに取り組んでいます。当初はByteArrayInputStreamを使用しました。コードを見て、私はすべての機能が同期していることに気付きました。このプロジェクトではこれは不要だったので、同期を外して書き直しました。私は、同期の一般的なコストがこの状況で私のために何だったのかを知りたいと決めました。

私はちょうど見るために簡単なテストを嘲笑した。私はSystem.nanoTime()ですべてをタイムアウトし、Java 1.6_20 x86と1.7.0-b147 AMD64と1.7_15 AMD64を使用し、-serverを使用しました。私はAMD64のバージョンがアーキテクチャーだけに基づいてパフォーマンスを上回り、Java 7のメリットがあることを期待していました。私は25番、50番、75番パーセンタイル(青、赤、緑)も見ました。しかし、サーバなしの1.6は、他のすべての構成のズボンを打ち負かしました。 graph

だから私の質問です。 1.7にデフォルトでオンになっているパフォーマンスに影響を与える1.6 -serverオプションには何がありますか?

私は1.7の速度向上の大部分が、1.6のより根本的なパフォーマンスオプションの一部をデフォルトにしていることを知っていますが、そのうちの1つがパフォーマンスの違いを引き起こしています。私はちょうど見るものを知らない。

public class ByteInputStream extends InputStream { 

public static void main(String args[]) throws IOException { 
    String song = "This is the song that never ends"; 
    byte[] data = song.getBytes(); 
    byte[] read = new byte[data.length]; 
    ByteArrayInputStream bais = new ByteArrayInputStream(data); 
    ByteInputStream bis = new ByteInputStream(data); 

    long startTime, endTime; 

    for (int i = 0; i < 10; i++) { 
     /*code for ByteInputStream*/ 
     /* 
     startTime = System.nanoTime(); 
     for (int ctr = 0; ctr < 1000; ctr++) { 
      bis.mark(0); 
      bis.read(read); 
      bis.reset(); 
     } 
     endTime = System.nanoTime(); 

     System.out.println(endTime - startTime); 
     */ 

     /*code for ByteArrayInputStream*/ 
     startTime = System.nanoTime(); 
     for (int ctr = 0; ctr < 1000; ctr++) { 
      bais.mark(0); 
      bais.read(read); 
      bais.reset(); 
     } 
     endTime = System.nanoTime(); 

     System.out.println(endTime - startTime); 
    } 

} 

private final byte[] array; 
private int pos; 
private int min; 
private int max; 
private int mark; 

public ByteInputStream(byte[] array) { 
    this(array, 0, array.length); 
} 

public ByteInputStream(byte[] array, int offset, int length) { 
    min = offset; 
    max = offset + length; 
    this.array = array; 
    pos = offset; 
} 

@Override 
public int available() { 
    return max - pos; 
} 

@Override 
public boolean markSupported() { 
    return true; 
} 

@Override 
public void mark(int limit) { 
    mark = pos; 
} 

@Override 
public void reset() { 
    pos = mark; 
} 

@Override 
public long skip(long n) { 
    pos += n; 
    if (pos > max) { 
     pos = max; 
    } 
    return pos; 
} 

@Override 
public int read() throws IOException { 
    if (pos >= max) { 
     return -1; 
    } 
    return array[pos++] & 0xFF; 
} 

@Override 
public int read(byte b[], int off, int len) { 
    if (pos >= max) { 
     return -1; 
    } 
    if (pos + len > max) { 
     len = max - pos; 
    } 
    if (len <= 0) { 
     return 0; 
    } 
    System.arraycopy(array, pos, b, off, len); 
    pos += len; 
    return len; 
} 

@Override 
public void close() throws IOException { 
} 

}// end class 
+8

+1「暖め」適切です。 –

+9

私は反対意見を持っています。ここにはたくさんの言葉がありますが、かなりのグラフがありますが、実際のコンテンツはありません。あなたがコードを見せて、その結果をテーブルに記述しただけであれば、より多くの人があなたを助けることができます。それがそうであるように、あなたが得る可能性が高いのは推測です。もしできれば-1。 – parsifal

+0

Y軸には何がありますか? 1つではなく複数の繰り返しタスクを測定しましたか? GCが結果に干渉していないと確信していますか? – Dariusz

答えて

5

他の人があなたのテストはコアの問題を参照するには短すぎること、言っているように私は、と思う - グラフはnanoTimeを示しており、それは0.0006sに0.0001で完了し、測定されるコア部を意味します。

ディスカッション

-serverおよび-clientの重要な違いは、-serverはJVMが長い間前後になると予想し、したがって、より優れた長期的な結果のために早い段階での努力を費やすことです。-clientは、起動時間が短縮され、十分なパフォーマンスが得られるようにします。

特に、ホットスポットはより最適化されて実行され、実行するCPUが増えます。つまり、-serverを使用すると、オプティマイザのコストがオプティマイザのコストを上回る可能性があります。

またReal differences between "java -server" and "java -client"?

を参照してください、あなたはまた、Java 7には、ホットスポットは、非常に高速でキックしない、tiered compilationの効果を見ることができます。 1000回の反復だけで、コードの完全な最適化は後で完了することはなく、そのメリットは少なくなります。

-Xprofオプションを指定してjavaを実行すると、JVMは、解釈されコンパイルされたさまざまなメソッドで費やされた時間に関するデータをダンプします。 。 分 - ホットスポットが蹴ら前に、それはコンパイルされたものについての考え、および(CPU)時間の比率を与える必要があり

をしかし、真の画像を取得するために、あなたは本当にこの長い多くを実行する必要があります、ミリ秒ではなく、JavaとOSのウォームアップを可能にします。 mainでテストをループする方が良いでしょう(計装されたメインテストループを含むループがあるので)、ウォームアップを無視することができます。分

EDIT変更秒はそのホットスポットを確保するために、JVMおよびOSは非常にいいグラフとよく文書質問に対する

+0

と、いくつかの特定のアプリケーションのランタイムパフォーマンスを測定したい場合は、数時間実行されるものとWebアプリケーションが24時間365日実行されるものがあります。負荷を重視することもありますが、ときどきそうしないこともあります。これは関連するユースケースです。最初のミリ秒や秒で何が起こるかは関係ありません。 – eis

+0

@eis:聞いています。ここでは、(実際のコードとは異なり)コードパスが1つしかなく、(I/Oエフェクトを持たずに)CPUにバインドされているので、時間がかかる可能性がありますこの場合、オーバーキル*。私はミリ秒単位であなたと完全に一致しています。 –

関連する問題