Java 为什么加密数据的第一次枚举需要这么长时间
我想创建一个性能测试,在这个测试中,我使用AES和PKCPadding5/7加密数据,这取决于aix系统上的提供程序(IBM或BouncyCastle)。我的问题是为什么第一次枚举如此之慢,而另一次枚举如此之快 当我使用参数运行测试时:Java 为什么加密数据的第一次枚举需要这么长时间,java,performance,encryption,Java,Performance,Encryption,我想创建一个性能测试,在这个测试中,我使用AES和PKCPadding5/7加密数据,这取决于aix系统上的提供程序(IBM或BouncyCastle)。我的问题是为什么第一次枚举如此之慢,而另一次枚举如此之快 当我使用参数运行测试时: Padding: AES/CBC/PKCS7Padding Provider: BC version 1.47 Number of iteration: 1000 结果是: Time: 392080057 ns Time: 174662 ns Time: 16
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
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
参数
Padding: AES/CBC/PKCS5Padding
Provider: IBMJCE version 1.7
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
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
代码:
为什么?修改后的答案 在第一次调用时加载和JIT编译代码需要花费时间——这就是为什么基准测试通常不包括第一次运行。(事实上,许多JVM越来越积极地重新进行JIT,因此性能会随着时间的推移而提高——因此好的基准测试在计时之前会运行代码很多次。) 此外,认为加密提供者可能会进行一些一次性设置也不是不合理的,特别是如果它正在尽最大努力获得一些合适的熵。(例如,它可以在内部使用
SecureRandom
)您可能希望分别对Cipher.getInstance
、Cipher.init
和Cypher.doFinal
方法调用计时,以确定哪一个是较慢的部分
最后,您还没有向我们展示所有的代码(generateevectot
?),因此可能存在一些潜在的东西
初始答案
显然,randomString
是:
一个简单的函数,它生成具有一定长度的随机字符串,是的,它使用SecureRandom,该实例只被装箱一次 考虑到您正在寻找一些昂贵的东西(如创建和使用
SecureRandom
实例),而且只发生一次,我觉得这听起来像是一把冒烟的枪
我建议您在randomString
中添加计时(使用,而不是System.currentTimeMillis
),以检验该假设
我还强烈建议您不要使用使用使用平台默认编码的
String.getBytes
重载,而是始终明确指定编码。加密提供程序通常需要一些加载。这可以通过强制加载来查看。这里我尝试使用IBM JCE提供程序):
给出:
Time to load: 72
我的猜测是,您在第一次使用提供商提供的任何内容时就点击了此加载。什么是
randomString
?它是否碰巧使用了SecureRandom
?生成具有特定长度的随机字符串的简单函数,是的,使用SecureRandom,一次装入哪个实例,而SecureRandom
通常是一个需要一些熵才能开始的函数,它来自以下内容。这可能需要一些时间,所有的类加载也是如此(每个类大约50毫秒,那里有很多类)。我从计算的时间中提取了randomString,但结果仍然是一样的。见更新code@hudi:您根本没有更新结果-如果您得到完全相同的结果,即使运行相同的代码,更不用说运行不同的代码,我会感到惊讶。是的,我更新的代码和结果是完全相同的。你对随机字符串的回答并不能解释为什么第一次迭代如此之长,而另一次迭代如此之快,即使生成随机字符串仍然是如此same@hudi:我已经更新了答案,包括类加载和JIT。不过我还是很怀疑这些数字。。。通常情况下,我希望基准会随着时间的推移而有所变化。虽然您使用的是currentTimeMillis
,但您并没有使用非常精确的计时器…@hudi:好的,答案再次更新。基本上,这并不让我感到惊讶,但是您可以执行更多的诊断来找出慢的部分是什么。这就解决了为什么BC需要如此长的时间,因为此提供程序不是默认添加到java提供程序中的
Time to load: 72