【问题标题】:Cost to XOR byte array seems to be very very low, lower than arraycopyXOR 字节数组的成本似乎非常低,低于 arraycopy
【发布时间】: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


【解决方案1】:

我是个彻头彻尾的白痴,我的大脑被关闭了。速度差异与 XOR 与 arraycopy 无关,与方法末尾进入 messageDigest 的数组大小有关。显然散列一个 BLOCKSIZE 数组会比一个 2*BLOCKSIZE 数组快。

【讨论】:

    【解决方案2】:

    我正在加密一个 1MB 字节数组几次...

    由于 Java 执行环境的复杂性,对 Java 代码进行基准测试存在许多陷阱。

    简单地运行代码几次并计时,这听起来不像是一种适当的基准测试技术。

    在您从实验中得出任何结论之前,请务必阅读 How do I write a correct micro-benchmark in Java? 并遵循其中的建议。

    【讨论】:

    • 我运行的非常简单,只有几个类,一切都很简单。我确实从您的链接中向我的测试添加了一些东西,这表明垃圾收集器在我调用 arraycopy 时运行得更多,并且现在热身已经到位,一切都变得更快了。只是 XOR 仍然比附加这两个数组要快。
    • 进一步研究垃圾收集器,使用 arraycopy 的代码版本在加密数组时运行 gc 的次数比 XOR 多 5 或 6 次。这听起来像是对提高速度的合理解释吗?为什么 gc 运行得更多,我正在制作一个新数组并丢弃一个数组?
    猜你喜欢
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多