package scala.collection.parallel.benchmarks.hashtables
import scala.collection.parallel.benchmarks.generic.StandardParIterableBenches
import scala.collection.parallel.benchmarks.generic.Dummy
import scala.collection.parallel.benchmarks.generic.Operators
import scala.collection.parallel.mutable.ParHashMap
trait ParHashTableBenches[K, V] extends StandardParIterableBenches[(K, V), ParHashMap[K, V]] {
def nameOfCollection = "mutable.ParHashMap"
def comparisonMap = collection.mutable.Map()
val forkJoinPool = new scala.concurrent.forkjoin.ForkJoinPool
object Map2 extends IterableBenchCompanion {
override def defaultSize = 40000
override def comparisons = List("jhashtable")
def benchName = "map2";
def apply(sz: Int, p: Int, w: String) = new Map2(sz, p, w)
}
class Map2(val size: Int, val parallelism: Int, val runWhat: String)
extends IterableBench {
var result: Int = 0
def comparisonMap = collection.Map("jhashtable" -> runjhashtable _)
def runseq = {
val r = this.seqcoll.asInstanceOf[collection.mutable.HashMap[K, V]].map(operators.mapper2)
result = r.size
}
def runpar = {
result = this.parcoll.map(operators.mapper2).size
}
def runjhashtable = {
val jumap = new java.util.HashMap[K, V]()
val it = this.seqcoll.iterator
val f = operators.mapper2
while (it.hasNext) {
val p = f(it.next)
jumap.put(p._1, p._2)
}
result = jumap.size
}
override def reset = runWhat match {
case "jhashtable" => this.seqcoll = createSequential(size, parallelism)
case _ => super.reset
}
def companion = Map2
override def repetitionsPerRun = 50
override def printResults {
println("Size of last result: " + result)
}
}
object FlatMap2 extends IterableBenchCompanion {
override def defaultSize = 5000
def benchName = "flatmap2";
def apply(sz: Int, p: Int, w: String) = new FlatMap2(sz, p, w)
}
class FlatMap2(val size: Int, val parallelism: Int, val runWhat: String)
extends IterableBench {
def comparisonMap = collection.Map()
override def repetitionsPerRun = 25
def runseq = this.seqcoll.flatMap(operators.flatmapper)
def runpar = this.parcoll.flatMap(operators.flatmapper)
def companion = FlatMap2
}
object HeavyMap extends IterableBenchCompanion {
override def defaultSize = 5000
override def comparisons = List()
def benchName = "heavy-map";
def apply(sz: Int, p: Int, w: String) = new HeavyMap(sz, p, w)
}
class HeavyMap(val size: Int, val parallelism: Int, val runWhat: String)
extends IterableBench {
var result: Int = 0
def comparisonMap = collection.Map()
def runseq = {
val r = this.seqcoll.asInstanceOf[collection.mutable.HashMap[K, V]].map(operators.heavymapper)
result = r.size
}
def runpar = {
result = this.parcoll.map(operators.heavymapper).size
}
def companion = HeavyMap
override def repetitionsPerRun = 50
}
object Reduce2 extends IterableBenchCompanion {
override def defaultSize = 50000
override def comparisons = List()
def benchName = "reduce2";
def apply(sz: Int, p: Int, w: String) = new Reduce2(sz, p, w)
}
class Reduce2(val size: Int, val parallelism: Int, val runWhat: String)
extends IterableBench {
def comparisonMap = collection.Map()
def runseq = this.seqcoll.reduceLeft(operators.mediumreducer)
def runpar = this.parcoll.reduce(operators.mediumreducer)
def companion = Reduce2
}
object Foreach extends IterableBenchCompanion {
override def defaultSize = 50000
override def comparisons = List()
def benchName = "foreach";
def apply(sz: Int, p: Int, w: String) = new Foreach(sz, p, w)
}
class Foreach(val size: Int, val parallelism: Int, val runWhat: String)
extends IterableBench {
def comparisonMap = collection.Map()
def runseq = this.seqcoll.foreach(operators.foreachFun)
def runpar = this.parcoll.pforeach(operators.foreachFun)
def companion = Foreach
}
}
object RefParHashTableBenches extends ParHashTableBenches[Dummy, Dummy] {
type DPair = (Dummy, Dummy);
object ForeachSet extends IterableBenchCompanion {
override def defaultSize = 50000
override def comparisons = List()
def benchName = "foreach-set";
def apply(sz: Int, p: Int, w: String) = new ForeachSet(sz, p, w)
}
class ForeachSet(val size: Int, val parallelism: Int, val runWhat: String)
extends IterableBench {
val array = new Array[Int](size)
def comparisonMap = collection.Map()
def runseq = for (p <- this.seqcoll) array(p._1.in) += 1
def runpar = this.parcoll.pforeach { p => array(p._1.in) += 1 }
def companion = ForeachSet
override def onEnd {
for (i <- 0 until array.length) {
assert(array(i) == repetitionsPerRun * runs)
}
}
}
object operators extends Operators[DPair] {
def gcd(a: Int, b: Int): Int = {
val result = if (b == 0) a else {
gcd(b, a - b * (a / b))
}
result + 1000
}
def heavy(a: Int): Int = {
var i = 0
var sum = a
while (i < 3000) {
i += 1
sum += a + i
}
sum
}
val foreachFun = (t: DPair) => {
t
()
}
val reducer = (x: DPair, y: DPair) => {
//y._2.num = x._2.in + y._2.in
y
}
val mediumreducer = (x: DPair, y: DPair) => {
y._2.num = gcd(x._2.in, y._2.in)
y
}
val filterer = (p: DPair) => {
p._1.num % 2 == 0
}
val mapper = (p: DPair) => {
val a = p._1
a.num = a.in % 2
(a, p._2)
}
val flatmapper = (p: DPair) => {
for (i <- 0 until 20) yield p
}
override val mapper2 = (p: DPair) => {
val a = 1 //heavy(p._1.in)
(new Dummy(p._1.in * -2 + a), p._2)
}
val heavymapper = (p: DPair) => {
var i = -2000
var t = p._1.in
while (i < 0) {
t += (p._2.num - p._1.num) / 500
p._1.num += p._2.num + t
i += 1
}
(p._1, new Dummy(0))
}
val taker = (p: DPair) => true
val eachFun: DPair => Unit = { dp =>
dp._1.dummy
}
}
def createSequential(sz: Int, p: Int) = {
val ht = new collection.mutable.HashMap[Dummy, Dummy]
for (i <- 0 until sz) ht += ((new Dummy(i), new Dummy(i)))
ht
}
def createParallel(sz: Int, p: Int) = {
val phm = new ParHashMap[Dummy, Dummy]
for (i <- 0 until sz) phm += ((new Dummy(i), new Dummy(i)))
forkJoinPool.setParallelism(p)
collection.parallel.tasksupport.environment = forkJoinPool
phm
}
}