1

この小さなコードを使用して、どのメソッドがより高速かをテストしています。

public void test() {
  long start = System.currentTimeMillis();
  MyDate date = new MyDate();
  int max = 5000;

  for (int i = 0; i < max; i++) {
    Calendar.getInstance().getTimeInMillis(); // <--
  }

  System.out.println("Calendar instance delay: " + (System.currentTimeMillis() - start));
  start = System.currentTimeMillis();

  for (int i = 0; i < max; i++) {
    date.getMillis(); // <--
  }

  System.out.println("My date delay: " + (System.currentTimeMillis() - start));
}

ということで、基本的にはとの性能を比較してます(MyDateは私が作成したクラスです)。Calendar.getInstance().getTimeInMillis()MyDate.getMillis()

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

Calendar instance delay: 413
My date delay: 2

しかし、順序を逆にしたとき (最初に MyDate と呼ばれ、Calendar の後)、次のようになりました

My date delay: 247
Calendar instance delay: 119

を使用してみSystem.nanoTime()ましたが、同じことが起こりました。テストする最初のコードは、より時間がかかりました。

なぜこの違いが起こるのか、誰でも知っていますか?または、外部プロファイラー アプリケーション (純粋な Java コードのみ) を使用せずにコードを正確にプロファイリングする方法はありますか?

ありがとう。

4

3 に答える 3

4

「小さな」コードのパフォーマンスをテストするには、何度も呼び出す必要があります。そうしないと、JIT、キャッシング、および分岐予測の影響により、テストが台無しになります。応答するまでにかかる時間を確認するために電話をかけた場合、数秒前に電話した場合とはまったく異なる応答が得られます。

于 2013-03-03T01:05:46.283 に答える
1

パフォーマンスを測定するときは、JVM が最適化の一環として、副作用のないコードを除外する場合があることに注意してください。

これを回避するには、次のようにします。

for (int i = 0; i < max; i++) {
    long a = date.getMillis();
    if (a % 1000 == i) {
        System.out.print(a);
    }
}

注意すべきもう 1 つのことは、ホットスポットの最適化です。測定する前に、コードを「ウォームアップ」する必要があります。

于 2013-03-03T11:33:06.763 に答える
1

Commons lang には System.nanoTime を使用する StopWatch クラスがあり、

http://commons.apache.org/lang/

org.apache.commons.lang.time.StopWatch

于 2013-03-03T01:08:26.063 に答える