原来的
可能是因为toString.map使用了WrappedString隐式,而toString.toArray.map使用了WrappedArray隐式来解决map。
让我们看看map,定义在TraversableLike:
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
b.sizeHint(this)
for (x <- this) b += f(x)
b.result
}
WrappedString使用 aStringBuilder作为构建器:
def +=(x: Char): this.type = { append(x); this }
def append(x: Any): StringBuilder = {
underlying append String.valueOf(x)
this
}
String.valueOf调用在实例上Any使用 Java ,可能首先被装箱。这些额外的操作可能是速度差异的原因,而不是 Array 构建器的所谓较短的代码路径。Object.toStringChar
这是一个猜测,但必须测量。
编辑
修改后,一般观点仍然存在,但我提到了错误的隐含,因为这些toDigit方法返回一个 Int 序列(或类似),而不是我误读的翻译字符串。
toDigit使用LowPriorityImplicits.fallbackStringCanBuildFrom[T]: CanBuildFrom[String, T, immutable.IndexedSeq[T]], with T = Int,它只是遵循一般的 IndexedSeq 构建器。
toDigitFast使用 type 的直接 Array 隐式CanBuildFrom[Array[_], T, Array[T]],这无疑是更快的。
显式传递以下 CBFtoDigit会使这两种方法相提并论:
object FastStringToArrayBuild {
def canBuildFrom[T : ClassManifest] = new CanBuildFrom[String, T, Array[T]] {
private def newBuilder = scala.collection.mutable.ArrayBuilder.make()
def apply(from: String) = newBuilder
def apply() = newBuilder
}
}