Created
February 10, 2015 09:57
-
-
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
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 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