我正在尝试在数值处理库中实现张量(多维数组(。张量实现的签名如图所示(减少签名的不相关部分(:
final class Tensor[V](val data: Array[V], val shape: IndexedSeq[Int])
这里的一个问题是IndexedSeq[Int]
的性能(因为它们有scala.collection.Vector
支持(。作为一个数值处理库,性能在这里是一个大问题。我想将默认的Vector
支持的IndexedSeq
换成Array
支持的。
我想指出什么是最好的方法(除了从 Scala 集合中复制完整的IndexedSeq
代码并更改相关部分。谢谢。
这就足够了吗?
final class FastVector[+T](a: Array[T]) extends IndexedSeq[T] {
override def apply(idx: Int) = a(idx)
override def length = a.length
}
然后,您将使用 FastVector
作为IndexedSeq
类型。IndexedSeq
的所有能力都是由该特质的具体方法提供的,因此map
、filter
等也都可供您使用。
在您的示例中,您可以执行两项操作:
- 不要将
data
字段设为公共(即 val(,以便外部代码无法访问它 - 构造
data
数组 your-self,即在张量的构造函数中,这样在张量实例之外就没有任何对数组的引用
例如:
class Tensor[V] private (data: Array[V], shape: Array[Int])
object Tensor{
def vector[V](input: Seq[V]) = new Tensor(input.toArray, Array(1))
def matrix[V](input: Seq[V], w: Int, h: Int) = new Tensor(input.toArray, Array(w,h))
}
// example use
Tensor.vector(1 to 20)
Tensor.matrix(1 to 20, 5, 4)
此外,一般来说,Array 周围有一个包装器,它是一个 IndexedSeq:WrappedArray。你可以这样做,例如:val iSeq: IndexedSeq[Int] = Array(42)
和 Scala 会自动将数组包装成一个包装数组。