Kotlin - use Array<Double> or DoubleArray

天大地大妈咪最大 提交于 2021-02-18 17:49:11

问题


What is the main difference in these two:

val array: Array<Double> = arrayOf()

vs

val array: DoubleArray = doubleArrayOf()

I know that one is using primitive data type double and the second its object based countrepart Double.

Is there any penalty or disadvatnage in using plain DoubleArray?


Why I want to know:

I am using JNI and for Double, I have to call

 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);
 }

vs

jdoubleArray res = env->NewDoubleArray(elementCount);
env->SetDoubleArrayRegion(res, 0, elementCount, array);

回答1:


There is no penalty (in fact, it will be faster due to no boxing), but, as with primitive types in Java, it forces you to create specialized overloads of certain methods if you want to be able to use them with [Int/Double/etc]Array.

This has actually been discussed over at the Kotlin forums:

the memory layout of an array of integers is quite different from that of an array of object pointers.

Norswap's comment in that discussion summarizes the tradeoff quite well:

The native one [int[]/IntArray] is faster to read/write, but the wrapped [Integer[]/Array<Int>] does not need to be entirely converted each time it crosses a generic boundary.
#7, norswap

For example, a function accepting Array<Int> (Integer[] on the JVM) will not accept an IntArray (int[]).

You have already listed the only real difference, that one is compiled to the primitive double[] and the other to Double[]. However, Double[] is an array of objects, so any time you modify the array by setting a value to a double, or retrieve a double, boxing and unboxing will be performed, respectively.

It is usually recommended to use DoubleArray instead, for speed and memory reasons.

As an example of speed penalties due to the object wrappers, take a look at the start of this post, taken from 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);
}

Replacing Long with long brings runtime from 43 seconds down to 8 seconds.



来源:https://stackoverflow.com/questions/49391973/kotlin-use-arraydouble-or-doublearray

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!