2

DES キーの生成にかかる時間を測定し、平均値を見つけるために数回計算したいと考えています。

for (int x = 0; x < 10; x++)
{
     long startTime = System.currentTimeMillis();

     SecretKey key = KeyGenerator.getInstance("DES").generateKey();         

     long stopTime = System.currentTimeMillis();
     long elapsedTime = stopTime - startTime;
     System.out.println("Total Time Taken : " + elapsedTime);
}

しかし、結果は次のようになります

Total Time Taken : 251
Total Time Taken : 0
Total Time Taken : 0
Total Time Taken : 0
Total Time Taken : 0
Total Time Taken : 0
Total Time Taken : 0
Total Time Taken : 0
Total Time Taken : 0
Total Time Taken : 0

キー オブジェクトを null に設定してから System.gc(); を呼び出して破棄しようとしました。しかし、うまくいきませんでした。

この問題を克服するための提案やアイデア。

4

7 に答える 7

4

カウントを上げてください。currentTimeMillis() の分解能は、ハードウェアと OS の機能によって制限されます。特に、絶対的な正確なミリ秒まで実際に解決することはできません。300ミリ秒の範囲では正確ではないことがわかりました。

小さな間隔でより高い精度が必要な場合は、System.nanoTime() を試すこともできます。繰り返しますが、この関数の精度はオペレーティング システムに依存することに注意してください。前回この Linux を試したときは、Windows よりも正確な結果が得られたと思います。まだ真実かもしれませんし、そうでないかもしれません。

于 2011-01-24T04:12:53.733 に答える
2

が非常に高速な場合generateKey()は、2 つのタイミング コールの間に何回か繰り返し実行することをお勧めします。タイマーにはエラーがあり (タイマーの値を取得する際にオーバーヘッドが発生します)、タイマー間隔 (ここでは 1 ミリ秒) と同じかそれよりも速い時間を計ろうとすると、非常に不正確な結果が生成されます。キー生成だけで 1000 回実行される別のループを配置してみてください (ただし、外側のループ内にとどまります)。

于 2011-01-24T04:12:58.987 に答える
2

マイクロベンチマーキングは難しい。これには、Google のオープン ソース プロジェクトであるCaliperを使用することをお勧めします。

Java で正しいマイクロベンチマークを作成するにはどうすればよいですか?

于 2011-01-24T04:13:16.810 に答える
1

System.nanoTime()ナノ秒単位で時間を取得するために使用します。

System.nanoTime()ではなくを使用すると、より正確な時刻が得られますSystem.currentTimeMillis()。結果は次のようになります。

合計所要時間:687562592
合計所要時間:51328
合計所要時間:33838
合計所要時間:25474
合計所要時間:22432
合計所要時間:29656
合計所要時間:23192
合計所要時間:28516
合計所要時間:22812
合計所要時間:21672
于 2011-01-24T04:23:54.040 に答える
1

最初の呼び出しの 251 ミリ秒は、主に、JVM が「DES」アルゴリズムの正しいプロバイダーを検索し、それに関連付けられた状態を初期化することを表しています。

DES キーはランダムな 64 ビット値です (実際には 56 ビットですが、それは別の話です)。それを行うのに1ミリ秒もかからないと思います。

正確な時間を知りたい場合は、System.nanoTime() を使用してみてください。これは、正確にこのタイプのアプリケーションに対して、ナノ秒の解像度で時間を提供します (ただし、精度はそれよりも多少低くなる可能性があります)。

于 2011-01-24T04:18:51.827 に答える
1

定規で 10 セント硬貨の幅を測定するように、非常に小さな値を測定するのは難しい場合があります。スタック内の 10 個または 20 個を測定し、その測定値をスタック内のそれらの数で割った方がよいでしょう。

int iterations = 1000;

long startTime = System.currentTimeMillis();
for (int x = 0; x < iterations; x++) {
     SecretKey key = KeyGenerator.getInstance("DES").generateKey();         
}
long stopTime = System.currentTimeMillis();

long elapsedTime = stopTime - startTime;
double average = elapsedTime/((double) iterations);
System.out.println("Total Time Taken : " + average + " ms");
于 2011-01-24T04:32:57.900 に答える
0

これは、JVM ランタイムの最適化が原因である可能性があります。そのため、最初の実行でプロファイリングが実行され、その後の呼び出しでメソッドがはるかに高速に実行されます。

また、メソッドが原因である可能性もあります。最初の呼び出しでは、クラスのロード、オブジェクトの作成などの初期化作業を実行できます。

通常、Java コードのベンチマークを行うときは、最初のいくつかの呼び出しを破棄することをお勧めします。

編集:そして、あなたの場合、そのSecretKeyインスタンスをどこでも使用しない場合、JVMはそれがまったく必要ないと判断でき、そのコードはプロセスで呼び出されません。

于 2011-01-24T04:09:48.060 に答える