Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么加密数据的第一次枚举需要这么长时间_Java_Performance_Encryption - Fatal编程技术网

Java 为什么加密数据的第一次枚举需要这么长时间

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

我想创建一个性能测试,在这个测试中,我使用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: 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