我想测量生成DES Key所需的时间,我想多次计算它,以便我可以找到平均值。
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()来处置密钥对象;但它不起作用。
任何克服此问题的建议或想法。
答案 0 :(得分:4)
提高你的计数。 currentTimeMillis()分辨率功率受硬件和操作系统功能的限制。特别是,它无法实际解析为绝对精确的ms。我发现它在300毫秒范围内不准确。
如果您需要在较小的时间间隔内获得更好的精度,您可能还需要尝试System.nanoTime()。请注意,此功能的准确性将取决于操作系统。我相信我上次尝试使用Linux时会返回比Windows更准确的结果。可能或可能不是真的。
答案 1 :(得分:2)
如果generateKey()
非常快,您可能希望在两次定时调用之间运行一定数量的迭代。定时器有错误(并且在获取定时器的值时会有一些开销),因此尝试计时与定时器间隔(此处为1ms)一样快或更快的事情将产生非常不准确的结果。尝试在密钥生成周围放置一个运行1000次的独立循环(但仍在外循环中)。
答案 2 :(得分:2)
微工作台标记很难。我建议您使用Google的开源项目Caliper。
答案 3 :(得分:1)
初始调用中的251 ms主要表示JVM正在查找“DES”算法的正确提供程序,并初始化与其关联的状态。
DES密钥只是随机的64位值(好吧,实际上是56,但这是一个不同的故事)。我希望这样做不到一毫秒。
如果你想确切地知道多少时间,可以尝试使用System.nanoTime(),它可以为纳米级分辨率提供时间(尽管它的准确度可能会略低于此值)。
答案 4 :(得分:1)
使用System.nanoTime()
获取以纳秒为单位的时间。
如果您使用System.nanoTime()
而不是System.currentTimeMillis()
,您将获得更准确的时间。结果将如下所示:
Total Time Taken : 687562592 Total Time Taken : 51328 Total Time Taken : 33838 Total Time Taken : 25474 Total Time Taken : 22432 Total Time Taken : 29656 Total Time Taken : 23192 Total Time Taken : 28516 Total Time Taken : 22812 Total Time Taken : 21672
答案 5 :(得分:1)
很难测量一个非常小的值 - 比如试图用尺子测量一角钱的宽度。最好在堆叠中测量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");
答案 6 :(得分:0)
这可能是因为JVM运行时优化。因此,在第一次运行时,它执行分析,并在随后的调用方法上运行得更快。
也可能是因为方法 - 第一次调用可以做一些初始化工作,比如加载类,创建对象等等。
通常,在对java代码进行基准测试时,建议先放弃几次调用。
编辑:在你的情况下,如果你不在任何地方使用那个SecretKey实例,JVM可以决定根本不需要它,并且在这个过程中甚至不会调用该代码。