治療Array[T]
爲IndexedSeq[T]
很難簡化:長
Array(1: Byte): IndexedSeq[Byte] // trigger an Implicit View
wrapByteArray(Array(1: Byte)) // explicitly calling
拆箱會殺了你額外的間接層之前。
C:\>scala -Xprint:erasure -e "{val a = Array(1: Byte); val b1: Byte = a(0); val
b2 = (a: IndexedSeq[Byte])(0)}"
[[syntax trees at end of erasure]]// Scala source: scalacmd5680604016099242427.s
cala
val a: Array[Byte] = scala.Array.apply((1: Byte), scala.this.Predef.
wrapByteArray(Array[Byte]{}));
val b1: Byte = a.apply(0);
val b2: Byte = scala.Byte.unbox((scala.this.Predef.wrapByteArray(a): IndexedSeq).apply(0));
爲了避免這種情況,Scala集合庫應專門元素類型,在相同的風格Tuple1
和Tuple2
。我被告知這是計劃中的事情,但這比簡單地將@specialized
拍到任何地方都要多一點,所以我不知道需要多長時間。
UPDATE
是,WrappedArray
是可變的,雖然collection.IndexedSeq[Byte]
沒有方法發生變異,所以你可以只信任客戶不要投了一個可變接口。下一個版本的Scalaz將包括ImmutableArray,這可以防止這種情況發生。
拳擊自帶通過這種通用的方法檢索從集合元素:
trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self =>
def apply(idx: Int): A
}
在JVM的水平,這個簽名是類型擦除:
def apply(idx: Int): Object
如果集合包含原語,即AnyVal
的子類型,它們必須裝入相應的包裝器中才能從此方法返回。對於某些應用,這是一個主要的性能問題。整個庫都是用Java編寫的,以避免這種情況,特別是fastutils。
Annotation directed specialization被添加到Scala 2.8中,以指示編譯器生成針對原始類型的排列而定製的各種版本的類或方法。這已經被應用到標準庫中的一些地方,例如, TupleN
,ProductN
,Function{0, 1, 2}
。如果這也適用於收藏層次結構,則可以緩解該性能成本。
對不起,作爲一個斯卡拉新手我不明白你的例子。你是說使用Array [Byte]會做很多拆箱?另外我不確定如何觸發隱式視圖。我天真地添加了「:IndexedSeq [Byte]」之後我的數組實例化,但它抱怨「類型不匹配」。此外,wrapByteArray()似乎返回一個可變的IndexedSeq [Byte],而不是不可變的版本。 – 2010-07-28 15:00:41