2013-06-06 7 views
10

私はできるだけ速く作ることを目標にした数独解決アルゴリズムを持っています。このアルゴリズムをテストするために、私はそれを複数回実行し、平均を計算します。いくつかの奇妙な数字に気付いた後、私はすべての回を印刷することを決定し、この結果を得た:10〜15処刑後何度も実行した後にアルゴリズムが高速になるのはなぜですか? (Java)

Execution Time : 4.257746 ms (#1) 
Execution Time : 7.610686 ms (#2) 
Execution Time : 6.277609 ms (#3) 
Execution Time : 7.595707 ms (#4) 
Execution Time : 7.610131 ms (#5) 
Execution Time : 5.011104 ms (#6) 
Execution Time : 3.970937 ms (#7) 
Execution Time : 3.923783 ms (#8) 
Execution Time : 4.070238 ms (#9) 
Execution Time : 4.765347 ms (#10) 
Execution Time : 0.818264 ms (#11) 
Execution Time : 0.620216 ms (#12) 
Execution Time : 0.679021 ms (#13) 
Execution Time : 0.643516 ms (#14) 
Execution Time : 0.718408 ms (#15) 
Execution Time : 0.744481 ms (#16) 
Execution Time : 0.760569 ms (#17) 
Execution Time : 0.80384 ms (#18) 
Execution Time : 0.75946 ms (#19) 
Execution Time : 0.802176 ms (#20) 
Execution Time : 66.032508 ms : average = 3.3016254000000003 

を(それがランダムに変化)、アルゴリズムの性能が大幅に向上しています。数百回実行すると、最終的には約0.3msで安定します。 JITがこのループを実行する前にアルゴリズムを実行していることに注意してください。

また、ループを実行する前にスレッドを2秒間スリープさせると、すべての時間は1ms(+/- 0.2)になります。

さらに、私のループの前に約500回、一般的な数独(1対9の対角線を持つグリッド)を解くと、私の時間はすべて約0.3ms(+/- 0.02)です。

すべての解決は同じです。すべての値がリセットされます。

だから私の質問は何倍である:

- なぜ連続する各解き後に改善する時間が解決していますか?

- 10-15の解決後に解決時間が突然低下するのはなぜですか?

+1

JITは最初の実行時に最適化する必要はありません。実際、コードの最適化のコストは、コードの重要な部分(十分な頻度で実行されている)でないことが証明されない限り、コードの最適化のコストを正当化することはできないため、可能性はほとんどありません。 –

+7

あなたは恐らくSkynetに進化する恐れのあるスードクを解決する人工的な生命体を作りました。今すぐ終了し、ココナッツの販売を開始してください。 – Piovezan

+0

ホタルから熱い時間移動のターミネーターに支払う小さな値段。 – arynaq

答えて

14

JVMがそのメソッドを頻繁に呼び出し、特定の数を落札後JITは、そのメソッドをコンパイルしているためです。実際には、メソッドは最初に呼ばれたときにコンパイルされません。メソッドごとに、JVMはメソッドが呼び出されるたびにインクリメントされる呼び出し回数を保持します。コール・カウントがJIT compilation thresholdを超えるまで、JVMはメソッドを解釈します。呼び出しカウントがしきい値に達すると、JITは、次の時刻にJVMが呼び出されたときに高速に実行されるように、bytecodesをコンパイルして最適化します。したがって、あなたのケースでは、10から15までの(ランダムに)実行ごとにアルゴリズムのパフォーマンスが大幅に向上します。

+1

アプリケーション自体に、改善につながった何かがある可能性があります。たとえばキャッシュする。最初の実行時に、外部ストレージからポーリングされた可能性のあるデータがありましたが、その結果、同じデータがキャッシュから取得された可能性があります。 –

+0

@AlexKreutznaer:それはJITコンパイラでコードを最適化するために使用されています。 –

+0

はい、JITはそれ自体では比較的低レベルです。しかし、私は純粋なビジネスキャッシングについて話しています。たとえば、アプリケーションで企業が読み込まれる(まれに変化する)ため、キャッシュを使用すると処理時間が大幅に短縮される可能性があります。 JITはあなたのためにそれを行うことはできません。 –

2

ほとんどの場合、JVMはいくつかの実行後に実行を最適化しました。

さらに、アプリケーション自体が実行結果を改善した何かを実行している可能性があります。

あなたが実行していることを詳しく知ることなく、もっと正確に何かを言うのは難しいです。

外部リソース(データベース接続、JMSキュー/トピックなど)を使用していますか。 キャッシュを使用していますか?

重要

すべて...

+1

続き.......... –

+0

コメントを追加しました。 –

+0

私は純粋で単純なjavaを使用します。キューなし、キャッシュなし、スレッドなし、データベースなし。 アプリケーションは、ループ実行ごとにデータを完全にリセットします。 – Paradoxyde

関連する問題