原来的
可能是因为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.toString
Char
这是一个猜测,但必须测量。
编辑
修改后,一般观点仍然存在,但我提到了错误的隐含,因为这些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
}
}