Skip to content

Instantly share code, notes, and snippets.

@filippovitale
Created February 10, 2015 09:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save filippovitale/cba86684cc8dace2b854 to your computer and use it in GitHub Desktop.
Save filippovitale/cba86684cc8dace2b854 to your computer and use it in GitHub Desktop.
Source code related to the presentation: "Will it blend?" - ScalaSyd Episode 33 - February 2015
import org.scalameter.api._
import scala.collection.mutable
/**
* Source code related to the presentation: "Will it blend?"
* ScalaSyd Episode 33 - February 2015
*/
class BlendBenchmark extends PerformanceTest.OfflineReport {
def notThatRandomSet(setSize: Int): Set[Int] = (1 to setSize).toSet
def createRandomMaps(size: Int, overlapPercentage: Double, setSize: Int): (Map[String, Set[Int]], Map[String, Set[Int]]) = {
val totalUniqueTuples = (size * (2 - overlapPercentage)).toInt
val rows = (1 to totalUniqueTuples).map(_.toString -> notThatRandomSet(setSize)).toVector
// overlapping sets are equals
val ma = rows.take(size).toMap
val mb = rows.takeRight(size).toMap
(ma, mb)
}
performance of "Blend implementations" in {
val maps = for {
size <- Gen.range("size")(5000, 100000, 5000)
} yield createRandomMaps(size, overlapPercentage = 0.5, setSize = 3)
measure method "from immutable maps to immutable map" in {
using(maps) curve "mutable naive" in { case (ma, mb) => MutableNaive.blend(ma, mb)}
using(maps) curve "immutable naive" in { case (ma, mb) => ImmutableNaive.blend(ma, mb)}
using(maps) curve "mutable with cata" in { case (ma, mb) => MutableCata.blend(ma, mb)}
using(maps) curve "immutable with cata" in { case (ma, mb) => ImmutableCata.blend(ma, mb)}
import scalaz.syntax.semigroup._
import scalaz.std.map._
import scalaz.std.set._
using(maps) curve "semigroup" in { case (ma, mb) => ma |+| mb}
}
val mutableMaps = maps map { case (ma, mb) => (mutable.Map() ++ ma, mutable.Map() ++ mb)}
measure method "mutating ma in-place" in {
using(mutableMaps) curve "mutable naive" in { case (ma, mb) => InPlaceNaive.blend(ma, mb)}
using(mutableMaps) curve "mutable with cata" in { case (ma, mb) => InPlaceCata.blend(ma, mb)}
}
}
}
object MutableNaive {
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = {
val result = mutable.Map() ++ ma
mb foreach { case (k, v) =>
if (result.contains(k))
result += k -> (result(k) ++ v)
else
result += k -> v
}
result.toMap
}
}
object ImmutableNaive {
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = {
(ma /: mb) { case (result, (k, v)) =>
if (result.contains(k))
result + (k -> (result(k) ++ v))
else
result + (k -> v)
}
}
}
object MutableCata {
import scalaz.syntax.std.option._
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = {
val result = mutable.Map() ++ ma
mb foreach { case (k, v) =>
result += (k -> result.get(k).cata(_ ++ v, v))
}
result.toMap
}
}
object ImmutableCata {
import scalaz.syntax.std.option._
def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] =
(ma /: mb) { case (result, (k, v)) =>
result + (k -> result.get(k).cata(_ ++ v, v))
}
}
object InPlaceNaive {
def blend(ma: mutable.Map[String, Set[Int]], mb: mutable.Map[String, Set[Int]]): mutable.Map[String, Set[Int]] = {
val result = ma
mb foreach { case (k, v) =>
if (result.contains(k))
result += k -> (result(k) ++ v)
else
result += k -> v
}
result
}
}
object InPlaceCata {
import scalaz.syntax.std.option._
def blend(ma: mutable.Map[String, Set[Int]], mb: mutable.Map[String, Set[Int]]): mutable.Map[String, Set[Int]] = {
val result = ma
mb foreach { case (k, v) =>
result += (k -> result.get(k).cata(_ ++ v, v))
}
result
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment