我想创建性能测试,在其中我要通过PKCPadding5 / 7使用AES加密数据,这取决于aix系统上的提供程序(IBM或BouncyCastle)。我的问题是,为什么第一次枚举这么慢而其他那么快?
当我使用参数运行测试时:
Padding: AES/CBC/PKCS7Padding
Provider: BC version 1.47
Number of iteration: 1000
结果是:
Time: 392080057 ns
Time: 174662 ns
Time: 160906 ns
Time: 169938 ns
Time: 154344 ns
Time: 155125 ns
Time: 157344 ns
Time: 157203 ns
Time: 157611 ns
Time: 158123 ns
参数
Padding: AES/CBC/PKCS5Padding
Provider: IBMJCE version 1.7
Number of iteration: 1000
结果是:
Time: 13410344 ns
Time: 185007 ns
Time: 182562 ns
Time: 170687 ns
Time: 203156 ns
Time: 189980 ns
Time: 182608 ns
Time: 174670 ns
Time: 176842 ns
Time: 174463 ns
代码:
for (int j = 0; j < pocetIteraci; j++) {
String text = randomString(46);
long time = System.currentTimeMillis();
sifruj(padding, provider, generateVectot(),text);
time = System.currentTimeMillis() - time;
System.out.println("Time: " + time + " ms");
}
public static byte[] sifruj(String padding, Provider provider, IvParameterSpec finalniInicializacniVektor,String text)
throws Exception {
return zpracuj(padding, provider, text.getBytes("UTF-8"), finalniInicializacniVektor, Cipher.ENCRYPT_MODE);
}
public static byte[] zpracuj(String padding, Provider provider, byte[] data,
IvParameterSpec finalniInicializacniVektor, int mode) throws Exception {
final SecretKeySpec klicSpec = new SecretKeySpec(klic, ALGORITHM_AES);
final Cipher sifra = Cipher.getInstance(padding, provider);
sifra.init(mode, klicSpec, finalniInicializacniVektor);
return sifra.doFinal(data);
}
更新:
创建密码的第一个实例时,最大的不同(正如我预期的那样):
long timeTemp = System.nanoTime();
final Cipher sifra = Cipher.getInstance(padding, provider);
timeTemp = System.nanoTime() - timeTemp;
System.out.println("XXXXXXXXXXXXXXXXX " + timeTemp + " ns");
为什么?
修改后的答案
在第一次调用时需要花费一些时间来加载和JIT编译代码-这就是为什么基准测试通常不包含第一次运行的原因。(实际上,许多JVM越来越积极地重新进行JIT,因此性能会随着时间的推移而提高-因此,良好的基准测试会在计时之前多次运行代码。)
此外,认为加密提供者可以很好地进行一次一次性设置并不是没有道理的,特别是如果加密提供者正在尽力获得一些体面的熵的话。(SecureRandom
例如,它可能在内部使用。)您可能想对Cipher.getInstance
,Cipher.init
和Cypher.doFinal
方法调用分别计时,以确定哪个是速度较慢的部分。
最后,您没有向我们展示所有代码(generateVectot
?),所以可能有些东西潜伏在那里。
最初的答案
显然randomString
是:
一个简单的函数,它生成具有一定长度的随机字符串,是的是使用SecureRandom,该实例仅创建一次
鉴于您正在寻找昂贵的东西(就像创建和使用SecureRandom
实例一样),并且只会发生一次,所以这听起来像是我的烟枪。
我建议您在其中添加时间(使用System.nanoTime
,而不是System.currentTimeMillis
)randomString
来测试该假设。
我也强烈建议您不要使用String.getBytes
平台默认编码的重载-而是始终明确指定编码。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句