0

こんにちは、ArrayList ソース コードを java.util パッケージから自分のパッケージにコピーしました。しかし、元の java.util.ArrayList よりも適切に実行されていることがわかりました。

テストコード:

@Test
public void jdkApiPerformance() {
    long startTime = System.nanoTime();
    java.util.ArrayList<Object> list = new java.util.ArrayList<Object>();
    long costTime = System.nanoTime() - startTime;
    System.out.println("jdkPerformance cost " + costTime + "ns.");
}

@Test
public void myApiPerformance() {
    long startTime = System.nanoTime();
    question.jdk.ArrayList<Object> list = new question.jdk.ArrayList<Object>();
    long costTime = System.nanoTime() - startTime;
    System.out.println("apiPerformance cost " + costTime + "ns.");
}

このテストの出力は次のとおりです。

jdkPerformance コストは 10263ns です。
apiPerformance コストは 1244158ns です。

明らかに、私の API は JDK API よりも遅く実行されます。

次に、このテスト用に @Before メソッドを追加しました。

@Before
public void setUp() {
    new java.util.ArrayList<Object>();
    new question.jdk.ArrayList<Object>();
}

この場合の出力は次のように変更されます。

jdkPerformance コストは 9932ns です。
apiPerformance コストは 1324ns です。

私の API は JDK API よりも高速に実行されます!!?

私はこの状況について本当に混乱しています.Plsは私を助けてくれます.ありがとう.

4

2 に答える 2

2

1)を使用System.nanoTime()すると、オペレーティングシステムのスケジューラの粒度に依存するため、結果が歪む可能性があります。

このメソッドはナノ秒の精度を提供しますが、必ずしもナノ秒の解像度(つまり、値が変更される頻度)ではありません。解像度が少なくともcurrentTimeMillis()の解像度と同じである場合を除いて、保証は行われません。

2)意味のあるベンチマークを得るには、最初にJVMをウォームアップする必要があります

3)調査には、ベンチマークライブラリの1つを使用できます。

4)一般的に、あなたの質問に対する答えは次のとおりです。はい、状況によっては、Sun / OracleのJVMはMath.sqrt()、特定のOS /ハードウェア用に最適化された実装のように、一部のJDKコードをホット置換します。

于 2013-03-05T02:47:42.143 に答える
1
  • JVM はオンデマンドでクラスをロードします。java.util.ArrayList は非常に基本的なクラスであるため、ベンチマークが開始される前にすでにロードされている可能性がありますが、おそらく初めて question.jdkArrayList が使用されます。これには、クラス ファイルを読み取るためのディスク I/O が含まれます。これは、新しいインスタンスを作成するよりも桁違いに時間がかかります。さらに、java.util.ArrayList は、JIT コンパイラーによって最適化されている可能性が高くなります。

  • System.nanoTime() は、その javadoc によると、「ナノ秒の精度ですが、必ずしもナノ秒の精度ではありません」。それを使用してマイクロ秒単位の遅延を測定するのは、せいぜいチャンスです。さらに、CPU 時間ではなく実測時間を測定します。CPU が他の方法で占有されている場合 (たとえば、開発環境でコンソール ビューを描画している場合)、報告された時間にカウントされます。

于 2013-03-05T02:50:40.620 に答える