Created
December 19, 2013 13:40
-
-
Save ccocchi/8039226 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.annotation.tailrec | |
import scala.collection.immutable.Seq | |
object Benchmark { | |
def main(args:Array[String]){ | |
val smallSeq = Seq(1, "foo") | |
val twoTypesSeq = ((1 to 100) map (n => 1)) ++ ((1 to 100) map (n => "I am a fucking String")) | |
println("With small seq") | |
runTest(partitionMutable, "mutable")(smallSeq) | |
runTest(partitionBuilder, "builder")(smallSeq) | |
runTest(partitionTailRecursion, "recurs")(smallSeq) | |
println("With medium seq") | |
runTest(partitionMutable, "mutable")(twoTypesSeq) | |
runTest(partitionBuilder, "builder")(twoTypesSeq) | |
runTest(partitionTailRecursion, "recurs")(twoTypesSeq) | |
} | |
def runTest(f: (Seq[Any] => (Seq[Int], Seq[String])), label: String)(s: Seq[Any]): Unit = { | |
var i = 10000 | |
val t0 = System.currentTimeMillis() | |
while (i > 0) { | |
f(s) | |
i -= 1 | |
} | |
val t1 = System.currentTimeMillis() | |
println(s"\t$label\t\t${t1 - t0}ms") | |
} | |
/** | |
* Method 1 with tail recursion | |
*/ | |
def partitionTailRecursion(seq: Seq[Any]): (Seq[Int], Seq[String]) = { | |
@tailrec | |
def iter(seq: Seq[Any], seqInt: Seq[Int], seqString: Seq[String]): (Seq[Int], Seq[String]) = { | |
seq match { | |
case Nil => (seqInt, seqString) | |
case (n: Int) :: tail => iter(tail, seqInt :+ n, seqString) | |
case (s: String) :: tail => iter(tail, seqInt, seqString :+ s) | |
} | |
} | |
iter(seq.toList, Seq.empty, Seq.empty) | |
} | |
/** | |
* Method 2 with vars | |
*/ | |
def partitionMutable(seq: Seq[Any]): (Seq[Int], Seq[String]) = { | |
val seqInt = scala.collection.mutable.ListBuffer[Int]() | |
val seqString = scala.collection.mutable.ListBuffer[String]() | |
seq.foreach { | |
case n: Int => seqInt += n | |
case s: String => seqString += s | |
} | |
(seqInt.toList, seqString.toList) | |
} | |
/** | |
* Method 3 with Builder | |
*/ | |
def partitionBuilder(seq: Seq[Any]): (Seq[Int], Seq[String]) = { | |
val seqInt = Seq.newBuilder[Int] | |
val seqString = Seq.newBuilder[String] | |
seq.foreach { | |
case n: Int => seqInt += n | |
case s: String => seqString += s | |
} | |
(seqInt.result(), seqString.result()) | |
} | |
} | |
Results: | |
With small seq | |
mutable 38ms | |
builder 23ms | |
recurs 56ms | |
With medium seq | |
mutable 77ms | |
builder 45ms | |
recurs 3756ms |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment