test1()がtest2()よりもはるかに高速に実行されるのはなぜですか?

user2219372
import java.util.Random;


public class Test{
    static int r = new Random().nextInt(2);
    static int a(){
        return r==1 ? 1 :0;
    }

    public static void test1() throws  Exception {
        //
        System.out.println(1403187139018L);
        for (int i = 0; i <   1073741824; i++) {}//*

        // Thread.sleep(20000);
        long d = 0;

        for (int j = 0; j < 10; j++) {
            long y = System.currentTimeMillis();

            for (int x = 0; x < 1073741823; x++) {
                d += r==0?1:0;
            }
            System.out.println((System.currentTimeMillis() -y));
        }
    }

    public static void test2()  throws  Exception{

        // Thread.sleep(20000);
        long d = 0;

        for (int j = 0; j < 10; j++) {
            long y = System.currentTimeMillis();

            for (int x = 0; x < 1073741824; x++) {
                d += r==0?1:0;
            }
            System.out.println((System.currentTimeMillis() -y));

            // System.out.println("time:"+ (System.currentTimeMillis() - y));
        }
    }

    public static void main(String[] args) throws  Exception{
        // Thread.sleep(20000);

        test1();
        test2();

    }

}

上記のコードを実行すると、次の出力が得られます。

32
26
28
28
32
29
35
33
30
31
1321
1308
1324
1277
1348
1321
1337
1413
1287
1331

test1がはるかに高速なのはなぜですか?

以下を除いて違いはありません。

System.out.println(1403187139018L);
for (int i = 0; i <   1073741824; i++) {}//*

また、test1の時間コストは25〜35ミリ秒で、信じられないほどです。同じコードをCで記述しましたが、すべてのforループを実行するのに約4秒かかりました。

この振る舞いは奇妙に思えます。追加するタイミングを知るにはどうすればよいですか。

System.out.println(1403187139018L);
for (int i = 0; i <   1073741824; i++) {}//*

また、私が変更した場合

r==0?1:0

a()

その場合、test2()はtest1()よりも高速に実行されます。

私が得る出力は次のとおりです。

1403187139018
3726
3729
3619
3602
3797
4362
4498
3816
4143
4368
1673
1386
1388
1323
1296
1337
1294
1283
1235
1460

元のレガシーコード:..。

long t = System.currentTimeMillis();
MappedByteBuffer mbb = map(new File("temp.mmp"), 1024L * 1024 * 1024);

System.out.println("load " + (System.currentTimeMillis() - t));//*
for (int i = 0; i < 2014L * 1024 * 1024; i++) {}//*
int d = 0;
for (int j = 0; j < 10; j++) {
    t = System.currentTimeMillis();
    mbb.position(0);
    mbb.limit(mbb.capacity());

    for (int i = 0; i < mbb.capacity(); i++) {
        d += mbb.get();
    }

    ....
}
System.out.println(d);
アパンギン

JITコンパイルに影響を与える要因が多すぎます。

  1. 実行統計。インタプリタがメソッドを実行している間、実行されるパス、実行される分岐、表示されるクラスインスタンスなど、さまざまなtest1統計が収集されます。統計では、最初の(空の)ループ内で収集されるため、実際の実行シナリオについてJITコンパイラがだまされます。 。
  2. クラスの初期化と珍しいトラップ。System.out.printlnから最初のものを削除すると、test1印刷に関連するすべてのクラスが初期化されるわけではありません。初期化されていないクラスのメソッドを呼び出そうとすると、珍しいトラップが発生し、最適化が解除され、新しい知識を使用してメソッドがさらに再コンパイルされます。
  3. で収集された間違った統計は、にtest1置き換えるr==0?1:0悪い冗談を言いますa()コンパイルでtest1は、メソッドa()はこれまで実行されたことがないため、最適化する機会がありませんでした。そのためtest2、の知識を使用してコンパイルされたものよりも動作が遅くなりますa()

もちろん、マイクロベンチマークを最初から書き込もうとすると、JITコンパイルに影響を与えるすべての要因を予測することは困難です。そのため、コードのベンチマークを行うための推奨される方法は、これらの問題のほとんどがすでに解決されている特別なフレームワークを使用することです。私は個人的にJMHを提案します。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

`test2()`メソッドは正常にコンパイルされますが、 `test1()`はコンパイルされないのはなぜですか?

分類Dev

この操作がGPUよりもCPUで高速に実行されるのはなぜですか?

分類Dev

このコードでCPUがGPUよりも高速に実行されるのはなぜですか?

分類Dev

ここでJavaがCよりも高速に実行されるのはなぜですか?

分類Dev

scipy線形補間が最近隣補間よりも高速に実行されるのはなぜですか?

分類Dev

C#がC ++よりも高速に実行されるのはなぜですか?

分類Dev

collections.Counterがソースコードを直接実行するよりも高速に実行されるのはなぜですか

分類Dev

代わりに、CPUがGPUよりも高速に行列演算を実行するのはなぜですか?

分類Dev

コードが想定よりもはるかに多く実行されるのはなぜですか?

分類Dev

バイトコードがネイティブコードよりも高速に実行される可能性があるのはなぜですか

分類Dev

EclipseのPyDevPythonコンソールよりもEclipseコンソールの方がコードが高速に実行されるのはなぜですか?

分類Dev

Python印刷がGoのfmt.Printおよびos.Stdout.Writeよりも高速に実行されるのはなぜですか

分類Dev

GPUがCPUよりも高速に行列乗算を実行できるのはなぜですか?

分類Dev

+ uvm_set_type_override = test1、test2も持つことで、+ UVM_TESTNAME = test1で指定されたuvmテストをオーバーライドすることは可能ですか?

分類Dev

setImmediate()がシーケンシャルコードよりも高速に実行されるのはなぜですか?

分類Dev

配列がArrayListよりもはるかに高速なのはなぜですか?

分類Dev

any()がinよりもはるかに高速なのはなぜですか?

分類Dev

コードのこの部分が他の部分よりも先に実行されるのはなぜですか?

分類Dev

pandas.grouby.meanが並列実装よりもはるかに高速なのはなぜですか

分類Dev

2番目のコードセグメントが最初のコードセグメントよりもはるかに高速に実行されるのはなぜですか?

分類Dev

この単純なループの実行において、PHP7がPython3よりもはるかに高速なのはなぜですか?

分類Dev

Python timeit.timeit-スニペットバージョンのsortは、ラムダを使用するよりも高速に実行されます。なぜですか?

分類Dev

フォルダ「test」を番号がicreasされた別のフォルダにコピーする方法test1、test2 test3

分類Dev

Pythonがmain()関数を介して独自の関数を実行するC ++よりも高速にC ++関数を実行するのはなぜですか?

分類Dev

「for」ループがループの本体よりも1回多く実行されるのはなぜですか?

分類Dev

ロギングライブラリによってパフォーマンステストがより高速に実行されるのはなぜですか?

分類Dev

ストリームを使用するこのコードがJava 9でJava 8よりもはるかに高速に実行されるのはなぜですか?

分類Dev

非同期コードが同期よりもはるかに高速であると見なされるのはなぜですか?

分類Dev

厳密な長さの関数が著しく高速に実行されるのはなぜですか?

Related 関連記事

  1. 1

    `test2()`メソッドは正常にコンパイルされますが、 `test1()`はコンパイルされないのはなぜですか?

  2. 2

    この操作がGPUよりもCPUで高速に実行されるのはなぜですか?

  3. 3

    このコードでCPUがGPUよりも高速に実行されるのはなぜですか?

  4. 4

    ここでJavaがCよりも高速に実行されるのはなぜですか?

  5. 5

    scipy線形補間が最近隣補間よりも高速に実行されるのはなぜですか?

  6. 6

    C#がC ++よりも高速に実行されるのはなぜですか?

  7. 7

    collections.Counterがソースコードを直接実行するよりも高速に実行されるのはなぜですか

  8. 8

    代わりに、CPUがGPUよりも高速に行列演算を実行するのはなぜですか?

  9. 9

    コードが想定よりもはるかに多く実行されるのはなぜですか?

  10. 10

    バイトコードがネイティブコードよりも高速に実行される可能性があるのはなぜですか

  11. 11

    EclipseのPyDevPythonコンソールよりもEclipseコンソールの方がコードが高速に実行されるのはなぜですか?

  12. 12

    Python印刷がGoのfmt.Printおよびos.Stdout.Writeよりも高速に実行されるのはなぜですか

  13. 13

    GPUがCPUよりも高速に行列乗算を実行できるのはなぜですか?

  14. 14

    + uvm_set_type_override = test1、test2も持つことで、+ UVM_TESTNAME = test1で指定されたuvmテストをオーバーライドすることは可能ですか?

  15. 15

    setImmediate()がシーケンシャルコードよりも高速に実行されるのはなぜですか?

  16. 16

    配列がArrayListよりもはるかに高速なのはなぜですか?

  17. 17

    any()がinよりもはるかに高速なのはなぜですか?

  18. 18

    コードのこの部分が他の部分よりも先に実行されるのはなぜですか?

  19. 19

    pandas.grouby.meanが並列実装よりもはるかに高速なのはなぜですか

  20. 20

    2番目のコードセグメントが最初のコードセグメントよりもはるかに高速に実行されるのはなぜですか?

  21. 21

    この単純なループの実行において、PHP7がPython3よりもはるかに高速なのはなぜですか?

  22. 22

    Python timeit.timeit-スニペットバージョンのsortは、ラムダを使用するよりも高速に実行されます。なぜですか?

  23. 23

    フォルダ「test」を番号がicreasされた別のフォルダにコピーする方法test1、test2 test3

  24. 24

    Pythonがmain()関数を介して独自の関数を実行するC ++よりも高速にC ++関数を実行するのはなぜですか?

  25. 25

    「for」ループがループの本体よりも1回多く実行されるのはなぜですか?

  26. 26

    ロギングライブラリによってパフォーマンステストがより高速に実行されるのはなぜですか?

  27. 27

    ストリームを使用するこのコードがJava 9でJava 8よりもはるかに高速に実行されるのはなぜですか?

  28. 28

    非同期コードが同期よりもはるかに高速であると見なされるのはなぜですか?

  29. 29

    厳密な長さの関数が著しく高速に実行されるのはなぜですか?

ホットタグ

アーカイブ