Last active
January 7, 2018 21:02
-
-
Save mosser/3fd0a274af3e001bba9d2b1d5d15a26c to your computer and use it in GitHub Desktop.
Merging maps
This file contains 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.util.Random | |
// Context | |
case class Event(data: Map[String, Int]) | |
// Generate a random history of given size | |
def history(size: Int): Seq[Event] = { | |
for (i <- 1 to size) | |
yield Event((1 to Random.nextInt(10) map { | |
_ => Random.nextInt(10).toString -> Random.nextInt(100) | |
}).toMap) | |
} | |
// alternative #1 | |
def alt1(history: Seq[Event]): Map[String,Int]= { | |
val keys = history.flatMap(_.data.keySet).distinct | |
val tmp = keys.map { k => k -> history.flatMap(_.data.get(k)).sum } | |
tmp.toMap | |
} | |
// alternative #2 | |
def alt2(history: Seq[Event]): Map[String,Int] = | |
(Map[String, Int]() /: history) { (acc, elem) => | |
acc ++ elem.data.map { case (k, v) => k -> (acc.getOrElse(k, 0) + v) } | |
} | |
// Benchmark | |
def timer[T,U](setup: => T)(first: T => U, second: T => U): (U, Long, Long) = { | |
val ctx = setup | |
val t1S = System.nanoTime() | |
val r1 = first(ctx) | |
val t1E = System.nanoTime() | |
val r2 = second(ctx) | |
val t2E = System.nanoTime() | |
assert(r1 == r2) | |
(r1, t1E-t1S, t2E-t1E) | |
} | |
def benchmark(howMany: Int): Map[String, Double] = { | |
val times: Seq[(Long,Long)] = 1 to howMany map { _ => | |
val (_, t1, t2) = timer(history(10000))(h => alt1(h), h => alt2(h)) | |
(t1,t2) | |
} | |
Map( | |
"alt1" -> times.map {_._1}.sum / times.length , | |
"alt2" -> times.map {_._2}.sum / times.length | |
) | |
} | |
benchmark(100) | |
// inverting alt1 and alt2 in the bench, avoiding JVM side effects | |
def benchmark2(howMany: Int): Map[String, Double] = { | |
val times: Seq[(Long,Long)] = 1 to howMany map { _ => | |
val (_, t2, t1) = timer(history(10000))(h => alt2(h), h => alt1(h)) | |
(t1,t2) | |
} | |
Map( | |
"alt1" -> times.map {_._1}.sum / times.length , | |
"alt2" -> times.map {_._2}.sum / times.length | |
) | |
} | |
benchmark2(100) |
This file contains 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.util.Random | |
defined class Event | |
history: history[](val size: Int) => Seq[Event] | |
alt1: alt1[](val history: Seq[Event]) => Map[String,Int] | |
alt2: alt2[](val history: Seq[Event]) => Map[String,Int] | |
timer: timer[T,U](val setup: => T)(val first: T => U,val second: T => U) => (U, Long, Long) | |
benchmark: benchmark[](val howMany: Int) => Map[String,Double] | |
res0: Map[String,Double] = Map(alt1 -> 3.7475511E7, alt2 -> 1.4487694E7) | |
res1: Map[String,Double] = Map(alt1 -> 3.7172239E7, alt2 -> 1.2503222E7) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Pour générer les données tu as les méthodes Seq.fill qui sont bien pratiques :)
E.g.