25

Java 7 に関する私の一般的な経験から、Java 6 よりも高速であることがわかります。ただし、これが常に当てはまるとは限らないと思わせる十分な情報に出くわしました。

最初の情報は、ここにある Minecraft Snooper データから得られます。私の意図は、そのデータを調べて、Minecraft の起動に使用されるさまざまなスイッチの効果を判断することでした。たとえば、 -Xmx4096m を使用すると、パフォーマンスにマイナスまたはプラスの効果があるかどうかを知りたいと思いました。そこにたどり着く前に、使用されているさまざまなバージョンの Java を調べました。1.5 から 1.8 を使用する開発者まですべてをカバーします。一般に、Java のバージョンを上げると、fps パフォーマンスが向上します。1.6 のさまざまなバージョンを通して、この緩やかな上昇傾向が見られます。正直なところ、これほど多くの異なるバージョンの Java がまだ普及しているとは思っていませんでしたが、人々は更新を適切に実行していないと思います。

1.6 以降のバージョンでは、最高のピークが得られます。1.7 は平均で約 10 fps を実行し、1.6 の新しいバージョンよりは低くなりますが、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は、他のすべての構成よりも優れています。 グラフ

だから私の質問はです。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
4

1 に答える 1

5

他の人が言っているように、テストが短すぎてコアの問題を確認できないと思います.グラフはnanoTimeを示しており、測定されているコアセクションが0.0001から0.0006秒で完了することを意味します.

討論

-server と -client の主な違いは、-server は JVM が長期間存在することを想定しているため、長期的な結果を改善するために早い段階で労力を費やすことです。-client は、高速な起動時間と十分なパフォーマンスを目指しています。

特に、より多くの最適化を伴う hotspot の実行は、実行により多くの CPU を必要とします。つまり、-server を使用すると、オプティマイザのコストが最適化によるメリットを上回っている可能性があります。

「java -server」と「java -client」の実際の違いを参照してください。

あるいは、階層化されたコンパイルの影響が見られる場合もあります。Java 7 では、ホットスポットがそれほど速く開始されません。反復が 1000 回しかない場合、コードの完全な最適化は後で行われるため、メリットは少なくなります。

オプションを指定して java を実行すると-Xprof、JVM がさまざまなメソッド (解釈とコンパイルの両方) で費やされた時間に関するデータをダンプする場合、洞察が得られる場合があります。コンパイルされたものと、ホットスポットが開始されるまでの (CPU) 時間の比率についてのアイデアが得られるはずです。

ただし、実際の状況を把握するには、Java と OS がウォームアップできるように、ミリ秒単位ではなく、数秒単位で実行する必要があります。ウォームアップを無視できるように、テストをループインする(つまり、インストルメント化されたメイン テスト ループを含むループを作成する) ことをお勧めします。main

EDITホットスポット、jvm、およびOSが適切に「ウォームアップ」されるように、秒を分に変更しました

于 2013-03-01T10:59:40.237 に答える