【发布时间】:2014-01-31 02:30:07
【问题描述】:
我正在上一门加密课程,主要是作为一项学术练习,我一直在尝试获得尽可能高的速度。我发现对字节数组进行异或运算的成本非常低,但在相同大小的字节数组上使用 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;
}
cryptBlock 每 32 个字节调用一次,我对一个 1MB 字节的数组进行了几次加密,并平均了获得速度的时间。
注释掉 A 行,而不是 B 行或 C 行的运行时间(20MB/s)与不注释任何行所花费的时间相同,尽管对大约 3125000 个 32 字节的块进行了 XOR。
注释掉 B 和 C 行,但不注释 A 以 35MB/s 的速度运行
注释掉所有行(A、B 和 C)以 37MB/s 的速度运行
谁能解释一下?
编辑:我编写了一个小数组复制实现来比较速度,它在我的代码中的运行速度与 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];
}
}
【问题讨论】:
-
你如何衡量所涉及的时间?
-
由于执行环境的复杂性,对 Java 代码进行基准测试存在许多陷阱。请务必阅读stackoverflow.com/questions/504103/…
-
cryptBlock 的前两行让我很困惑。 Arrays.copyOf 创建整个 IV 数组的副本,然后将 BLOCKSIZE nr 个元素从 IV 复制到 iv。但是 iv 已经包含与 IV 完全相同的数据?
-
@Rickard 啊,没注意到。这是我之前做的一些调整的遗留物,我忘了把它拿出来。从问题中删除了这一行。
标签: java append jit xor arrays