在设计特定领域的数值计算库时寻找要使用的正确数据类型(例如 IndexedSeq[Double]
)。对于这个问题,我将范围限制为使用 Double
的一维数组。 .该库将定义一个数字函数,这些函数通常应用于一维数组中的每个元素。
注意事项:
Vector
或 IndexedSeq
我应该使用集合层次结构更高的东西,例如
Seq
?还是只定义单元素函数并将映射/迭代留给最终用户更好?
这似乎效率较低(因为某些计算可以在每组调用中完成一次),但同时也是一个更灵活的 API,因为它适用于任何类型的集合。
有什么建议吗?
最佳答案
如果您的计算是远程计算密集型的,请使用 Array
,原始的或包装在您自己的类中。您可以提供与集合兼容的包装器,但使其成为仅用于互操作性的显式包装器。除 Array
以外的所有内容是通用的,因此是盒装的,因此相对缓慢和笨重。
如果您不使用 Array
,人们将被迫放弃你拥有的任何东西而只使用 Array
相反,当性能很重要时。也许没关系;也许您希望计算是为了方便而不是效率。在这种情况下,我建议使用 IndexedSeq
对于界面,假设您想让人们知道索引不是非常慢(例如不是 List
),并使用 Vector
在引擎盖下。您将使用比 Array[Double]
多 4 倍的内存,并且对于大多数省力的操作(例如乘法)要慢 3-10 倍。
例如,这个:
val u = v.map(1.0 / _) // v is Vector[Double]
大约比这慢三倍:
val u = new Array[Double](v.length)
var j = 0
while (j<u.length) {
u(j) = 1.0/v(j) // v is Array[Double]
j += 1
}
如果您使用
map
方法在 Array
,它和 Vector[Double]
一样慢道路; Array
上的操作是通用的,因此是盒装的。 (这就是大部分处罚的来源。)
关于api - 用于矢量化数值计算的最佳 Scala 集合类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13726378/