【发布时间】:2020-04-09 02:04:24
【问题描述】:
我正在开发一个程序,其中我有 2 个字节数组并且需要计算它们之间的差异。例如,如果第一个数组是 {1, 2, 3},第二个数组是 {2, 3, 4},则差值为 3。
我目前的做法是这样的:
public long calculateDifference(byte[] a, byte[] b) {
long difference = 0;
for(int i = 0; i < a.length; i++) {
difference += Math.abs(a[i] - b[i]);
}
return difference;
}
但是,程序需要能够处理最多包含大约 5,000,000 个元素的字节数组,因此使用当前方法会太慢。
因为我有 16 个线程,所以我将并行流视为一种选择。但是因为没有 ByteStream,所以如果没有拆箱和装箱,就无法使用 reduce 和 collect 操作。
另一种选择是使用IntStream.range(0, byteArrayLength) 创建并行流并使用int 访问索引。但是,要做到这一点,LongAdder 或 AtomicLong 是必要的,这两者在我的基准测试中都要慢得多。 (LongAdder 内部好像用了一个数组,最后总结一下)
有没有更有效的方法来实现这一点?我不介意添加外部依赖项。谢谢!
【问题讨论】:
-
如果第一个数组是
{1,2,3},第二个数组是{0}怎么办?此外,5,000,000的添加可能花费的时间比您可以测量的要少。计算机每秒可以执行许多 数百万 次操作。 What is a gigaflop? 和 2014 a Core i7 5930K 在 3.5GHz 的 6 核中有 289 gigaflops。 -
@ElliottFrisch 我实际上正在制作一个遗传算法并会持续运行它,因此即使速度提高 20%,也可以节省数小时。
-
@Joni 请看我上面的评论。
-
注意 289 gigaflops 是 ~289,000,000,000 浮点 操作(每秒)。您将 500 万与近 3000 亿进行比较。小时?不需要几秒钟。
-
@ElliottFrisch 我实际上不知道时钟速度与每秒的浮点运算不同!但是,对于我的程序来说,吞吐量越大越好。
标签: java algorithm lambda java-stream array-difference