我正在进行加密课程,主要是作为学术练习,我一直在尝试以尽可能高的速度。我发现一些奇怪的事情,XOR'ing一个字节数组的成本非常低,但在相同大小的字节数组上使用arraycopy更昂贵。我认为它必须是一些JIT伏都教,并想知道是否有人可以解释它。
相关守则:
private byte[] cryptBlock(){
byte[] iv = Arrays.copyOf(IV, IV.length);
iv[blocNo % BLOCKSIZE] += blockNo + 1;
iv = Misc.cleanXOR(key, iv); //A
iv = Arrays.copyOf(iv, BLOCKSIZE + iv.length); //B
System.arraycopy(key, 0, iv, BLOCKSIZE, BLOCKSIZE); //C
return Misc.cleanXOR(buffer, mD.digest(iv));
}
public static byte[] cleanXOR(byte[] a, byte[] b){
byte[] c = new byte[a.length];
int i=0;
for (byte d : a)
c[i] = (byte) (d ^ b[i++]);
return c;
}
每隔32个字节调用一次cryptBlock,我正在加密一个1MB字节的数组,并平均时间来获得速度。
尽管在大约3125000个32字节的块上执行XOR操作,但注释掉A行,但不是B行或C行在相同的时间内(20MB / s)运行,而不是注释掉所有行。
注释掉B行和C行但不是A以35MB / s的速度运行
注释掉所有行(A,B和C)的运行速度为37MB / s
任何人都能解释一下吗?
编辑:我写了一个小的arraycopy实现来比较速度,它在我的代码中以与System.arraycopy一样快的速度运行。public static void arraycopy(byte[] source, int srcPos, byte[] dest, int destPos, int length){
for(int i = 0; i < length; i++){
dest[i + destPos] = source[i + srcPos];
}
}
答案 0 :(得分:1)
我正在加密一个1MB字节的数组几次 ......
由于Java执行环境的复杂性,对Java代码进行基准测试存在许多缺陷。
简单地运行代码并对其进行计时并不像是一种适当的基准测试技术。
在从实验中得出任何结论之前,请务必阅读How do I write a correct micro-benchmark in Java?并遵循其中的建议。
答案 1 :(得分:0)
我是一个完全白痴,我的大脑被关闭了。速度差异与XOR与arraycopy无关,而且与方法结束时进入messageDigest的数组大小有关。显然散列BLOCKSIZE数组会比2 * BLOCKSIZE数组快。