diff options
author | Denton Cockburn <kanielc@gmail.com> | 2014-12-15 21:58:46 -0500 |
---|---|---|
committer | Denton Cockburn <kanielc@gmail.com> | 2015-01-09 20:41:37 -0500 |
commit | d1d3225e28ed1847470d976ffeefbce40e90d9ac (patch) | |
tree | 4015a0c80561cf1ca7117f1604d4936a3ca1a982 /src | |
parent | 7ba38a07916426314cc3bff6999f3992757e0b26 (diff) | |
download | scala-d1d3225e28ed1847470d976ffeefbce40e90d9ac.tar.gz scala-d1d3225e28ed1847470d976ffeefbce40e90d9ac.tar.bz2 scala-d1d3225e28ed1847470d976ffeefbce40e90d9ac.zip |
SI-8988 Escaping character in StringLike.split(c) prevents usage of optimized String.split code path
Escaping a char when calling split is slow. We end up compiling a
Pattern to simply match a character literal.
Instead, we just use an loop with indexOf to construct our resulting
Array.
Current speed up over old behaviour is about 12-1
Diffstat (limited to 'src')
-rw-r--r-- | src/library/scala/collection/immutable/StringLike.scala | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala index f0daaf25a5..1ead894faf 100644 --- a/src/library/scala/collection/immutable/StringLike.scala +++ b/src/library/scala/collection/immutable/StringLike.scala @@ -10,7 +10,7 @@ package scala package collection package immutable -import mutable.Builder +import mutable.{ ArrayBuilder, Builder } import scala.util.matching.Regex import scala.math.ScalaNumber import scala.reflect.ClassTag @@ -203,8 +203,33 @@ self => private def escape(ch: Char): String = "\\Q" + ch + "\\E" - @throws(classOf[java.util.regex.PatternSyntaxException]) - def split(separator: Char): Array[String] = toString.split(escape(separator)) + def split(separator: Char): Array[String] = { + val thisString = toString + var pos = thisString.indexOf(separator) + + if (pos != -1) { + val res = new ArrayBuilder.ofRef[String] + + var prev = 0 + do { + res += thisString.substring(prev, pos) + prev = pos + 1 + pos = thisString.indexOf(separator, prev) + } while (pos != -1) + + if (prev != thisString.size) + res += thisString.substring(prev, thisString.size) + + val initialResult = res.result() + pos = initialResult.length + while (pos > 0 && initialResult(pos - 1).isEmpty) pos = pos - 1 + if (pos != initialResult.length) { + val trimmed = new Array[String](pos) + Array.copy(initialResult, 0, trimmed, 0, pos) + trimmed + } else initialResult + } else Array[String](thisString) + } @throws(classOf[java.util.regex.PatternSyntaxException]) def split(separators: Array[Char]): Array[String] = { |