diff options
author | Dima Tkach <dima@lookout.com> | 2016-06-28 07:26:45 -0400 |
---|---|---|
committer | Dima Tkach <dima@lookout.com> | 2016-06-28 10:03:09 -0400 |
commit | add83b8a8fea641c3ba96ed963c25c84ffe137fb (patch) | |
tree | 3004ef23a3f9ed1f5e1efb2c4a429945514816f8 | |
parent | 4e950838cbee187f3cee2ef197164792db74e56a (diff) | |
download | scala-add83b8a8fea641c3ba96ed963c25c84ffe137fb.tar.gz scala-add83b8a8fea641c3ba96ed963c25c84ffe137fb.tar.bz2 scala-add83b8a8fea641c3ba96ed963c25c84ffe137fb.zip |
Override `.slice` in ArrayOps to use arraycopy.
This makes it ~10x faster when copying large chunks arround.
My benchmark:
def bm(duration: Long)(f: => Unit): Int = {
val end = System.currentTimeMillis + duration
var count = 0
while(System.currentTimeMillis < end) {
f
count += 1
}
count
}
def measure(seconds: Int)(f: => Unit) = (1 to seconds).map { _ => bm(1000)(f) }.sum / seconds
val array = scala.util.Random.alphanumeric.take(1000).toArray
measure(20) { array.slice(100, 500) }
// ~5 million
measure(20) { scala.collection.WrappedArray(array).slice(100, 500) }
// ~300K
-rw-r--r-- | src/library/scala/collection/mutable/ArrayOps.scala | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala index 507585b9cf..b384decbfb 100644 --- a/src/library/scala/collection/mutable/ArrayOps.scala +++ b/src/library/scala/collection/mutable/ArrayOps.scala @@ -41,6 +41,17 @@ sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomPara if (l > 0) Array.copy(repr, 0, xs, start, l) } + override def slice(from: Int, until: Int): Array[T] = { + val lo = math.max(from, 0) + val hi = math.min(math.max(until, 0), repr.length) + val size = math.max(hi-lo, 0) + val result = java.lang.reflect.Array.newInstance(elementClass, size) + if(size > 0) { + Array.copy(repr, lo, result, 0, size) + } + result.asInstanceOf[Array[T]] + } + override def toArray[U >: T : ClassTag]: Array[U] = { val thatElementClass = implicitly[ClassTag[U]].runtimeClass if (elementClass eq thatElementClass) |