我知道Stack Overflow上可能有一些看似类似的问题;然而,我的问题不同。
我目前正在从事特定研究领域的数值计算,并继承了我的团队很早以前实现的一个Java包。我现在的任务是优化它的性能。该软件包广泛使用了ArrayList<Double>
。据我所知,由于Java泛型中的类型擦除,Java,至少到我正在使用的版本9,不支持原始类型
ArrayList
。这有几个问题:
存储开销:Double 是 double 的包装类。由于Double是一个对象,它包含一个对象头,占用8个字节。因此,每个Double对象占用16字节的内存。
非连续内存:ArrayList
内部使用数组来存储
Double
对象,即
Double[] data
。该数组保存对
Double
实例的引用。这些实例不连续存储在堆中。例如,如果
Double[] data = {1.0, 2.0}
,则数据中的引用是连续的,但这些引用指向的实际
Double
对象不是连续的。由于需要取消引用这些指针,这会导致局部性差和频繁的缓存未命中。
拆箱和自动装箱:使用 Double 进行比较和计算时,由于拆箱和自动装箱,会产生额外的开销。
DoubleArrayList
源代码中的所有 Object 替换为原始 double 来创建个人
ArrayList
是否可行?这种方法有哪些潜在的陷阱?
vector<double>
可用。
ArrayList
)而不是
double[]
。
double[]
。
ArrayList
的“自由”调整大小只是一种便利 - 当需要更多空间时,内部支持数组会被替换为两倍大,并使用旧式循环复制元素。您自己编写代码是一个简单的实现。
创建一个带有
double[]
字段的类,基本上从
ArrayList
复制您需要的内容,但为数组添加 getter 方法并将其用于计算。如果你能摆脱它,请使用
float[]
代替,因为
float
上的操作大约是
double
上的两倍。