Kotlin - 使用 Array<Double> 或 DoubleArray

Mar*_*rry 2 arrays kotlin

这两者的主要区别是什么:

val array: Array<Double> = arrayOf()
Run Code Online (Sandbox Code Playgroud)

对比

val array: DoubleArray = doubleArrayOf()
Run Code Online (Sandbox Code Playgroud)

我知道一个是使用原始数据类型double,第二个是基于对象的 countrepart Double

使用 plain 有什么惩罚或缺点DoubleArray吗?


为什么我想知道:

我正在使用 JNI 和 for Double,我必须打电话

 jclass doubleClass = env->FindClass("java/lang/Double");
 jmethodID doubleCtor = env->GetMethodID(doubleClass, "<init>", "(D)V");
 jobjectArray res = env->NewObjectArray(elementCount, doubleClass, nullptr);

 for (int i = 0; i < elementCount; i++){
    jobject javaDouble = env->NewObject(doubleClass, doubleCtor, array[i]);
    env->SetObjectArrayElement(res, i, javaDouble);
    env->DeleteLocalRef(javaDouble);
 }
Run Code Online (Sandbox Code Playgroud)

对比

jdoubleArray res = env->NewDoubleArray(elementCount);
env->SetDoubleArrayRegion(res, 0, elementCount, array);
Run Code Online (Sandbox Code Playgroud)

Moi*_*ira 5

没有惩罚(实际上,由于没有装箱,它会更快),但是,与 Java 中的原始类型一样,如果您希望能够将它们与[Int/Double/etc]Array.

这实际上已经在 Kotlin 论坛上讨论过

整数数组的内存布局与对象指针数组的内存布局完全不同。

Norswap 在该讨论中的评论很好地总结了权衡:

原生的 [ int[]/ IntArray] 读/写速度更快,但包装的 [ Integer[]/ Array<Int>] 不需要在每次跨越通用边界时完全转换。
#7,挪威交换

例如,接受Array<Int>Integer[]在 JVM 上)的函数将接受IntArray( int[])。

您已经列出了唯一真正的区别,即一个编译为原始类型double[],另一个编译为Double[]. 但是,Double[]是一个对象数组,因此任何时候通过将值设置为 adouble或检索 a来修改数组时,double都将分别执行装箱和拆箱。

DoubleArray出于速度和内存方面的原因,通常建议改用它。

作为对象包装器导致速度损失的一个例子,请看这篇文章的开头,摘自 Effective Java:

public static void main(String[] args) {
    Long sum = 0L; // uses Long, not long
    for (long i = 0; i <= Integer.MAX_VALUE; i++) {
        sum += i;
    }
    System.out.println(sum);
}
Run Code Online (Sandbox Code Playgroud)

替换Longlong将运行时间从 43 秒缩短到 8 秒。