如何在 Scala 中实现由数组支持的不可变 IndexedSeq
How to implement an immutable IndexedSeq in Scala, backed by an Array
我正在尝试在数值处理库中实现张量(多维数组)。 Tensor 实现的签名如图所示(删除签名中不相关的部分):
final class Tensor[V](val data: Array[V], val shape: IndexedSeq[Int])
这里的一个问题是 IndexedSeq[Int]
的性能(因为它们得到 scala.collection.Vector
的支持)。作为一个数值处理库,性能是这里的一个大问题。我想用 Array
支持的默认 Vector
支持的 IndexedSeq
换掉。
我想知道什么是最好的方法(除了从 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
字段设为 public(即 val),这样外部代码就无法访问它
- 构造
data
数组 your-self,即在 Tensor 的构造函数中,以便在 Tensor 实例之外没有任何对数组的引用
例如:
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 会自动将 Array 包装成 WrappedArray。
我正在尝试在数值处理库中实现张量(多维数组)。 Tensor 实现的签名如图所示(删除签名中不相关的部分):
final class Tensor[V](val data: Array[V], val shape: IndexedSeq[Int])
这里的一个问题是 IndexedSeq[Int]
的性能(因为它们得到 scala.collection.Vector
的支持)。作为一个数值处理库,性能是这里的一个大问题。我想用 Array
支持的默认 Vector
支持的 IndexedSeq
换掉。
我想知道什么是最好的方法(除了从 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
字段设为 public(即 val),这样外部代码就无法访问它 - 构造
data
数组 your-self,即在 Tensor 的构造函数中,以便在 Tensor 实例之外没有任何对数组的引用
例如:
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 会自动将 Array 包装成 WrappedArray。