これは私にとって本当に驚くべきことですが、処理が遅くなる内部メモリコピー がありますか?
ArrayOps.drop
内部コールごとに新しいArray
を生成ビルダーを割り当てた、IterableLike.slice
を呼び出します。
override def slice(from: Int, until: Int): Repr = {
val lo = math.max(from, 0)
val hi = math.min(math.max(until, 0), length)
val elems = math.max(hi - lo, 0)
val b = newBuilder
b.sizeHint(elems)
var i = lo
while (i < hi) {
b += self(i)
i += 1
}
b.result()
}
あなたが反復+割り当てのコストを見ています。これが何回起こったのか、何がコレクションのサイズなのかを指定していませんでしたが、大きければ時間がかかることがあります。
これを最適化する方法の1つは、コレクションを反復処理してhead
という要素を削除する代わりにList[String]
を生成することです。これは、リストを作成しArray[T]
の追加トラバーサルを発生し、そのベンチマークに、これはあなたが実際には何を得る見て確認します注意:
val items = s.split(" +").toList
val afterDrop = items.drop(2).mkString(" ")
別の可能性は、手動でmkString
の独自のバージョンを含めるようにArray[T]
を豊かにすることです
object RichOps {
implicit class RichArray[T](val arr: Array[T]) extends AnyVal {
def mkStringWithIndex(start: Int, end: Int, separator: String): String = {
var idx = start
val stringBuilder = new StringBuilder(end - start)
while (idx < end) {
stringBuilder.append(arr(idx))
if (idx != end - 1) {
stringBuilder.append(separator)
}
idx += 1
}
stringBuilder.toString()
}
}
}
そして今、我々は持っている::StringBuilder
を移入
object Test {
def main(args: Array[String]): Unit = {
import RichOps._
val items = "hello everyone and welcome".split(" ")
println(items.mkStringWithIndex(2, items.length, " "))
}
収率:
and welcome
'split'は' Array'を返します。 '配列'の場合。 'drop'はコピーを作る必要があります。 –