我需要在 Spark 中对 2 个非常大 (>1GB) 的 ByteArray 进行比特运算(因此使用 Scala)。
我正在寻找最有效的方法(在速度和内存方面),这意味着我不想使用诸如“zip”之类的方法将我的数组转换为列表。
目前,我正在使用以下方法,但我想知道你们中的一些人是否有其他想法......
def bitor(x: Array[Byte], y: Array[Byte]) : Array[Byte] = {
for(i <- 0 to x.size) {
x(i) = (x(i) | y(i)).toByte
}
return x
}
我应该通过 JNI 并在 native C 中计算它吗?
最佳答案
您使用 foreach
的代码将脱糖成等效的 java 代码:
public final class _$$anon$1$$anonfun$bitor$1 extends AbstractFunction1$mcVI$sp implements Serializable {
private final byte[] x$1;
private final byte[] y$1;
public _$$anon$1$$anonfun$bitor$1(byte[] x$1, byte[] y$1) {
this.x$1 = x$1;
this.y$1 = y$1;
}
@Override
public final void apply(final int i) {
this.apply$mcVI$sp(i);
}
@Override
public void apply$mcVI$sp(final int i) {
this.x$1[i] |= this.y$1[i];
}
}
private byte[] bitor(final byte[] x, final byte[] y) {
RichInt.to$extension0(Predef.intWrapper(0), Predef.byteArrayOps(x).size())
.foreach(new _$$anon$1$$anonfun$bitor$1(x, y));
return x;
}
但是,如果将 for
comprehension 替换为 while
,情况就会发生变化:
def bitor(x: Array[Byte], y: Array[Byte]) : Array[Byte] = {
var i = 0
while (i < x.length) {
x(i) = (x(i) | y(i)).toByte
i += 1
}
x
}
被转译为:
private byte[] bitor(final byte[] x, final byte[] y) {
for (int i = 0; i < x.length; ++i) {
x[i] |= y[i];
}
return x;
}
关于performance - 两个 Byte[Array] 的高效按位或,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36651343/