Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed preparation of inputs for benchmark #13

Merged
merged 1 commit into from
Mar 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,18 @@ To run the main methods:
$ ps -ef | sbt "runMain edu.luc.etl.osdi.processtree.scala.groupby.Main"
$ ps -ef | sbt "runMain edu.luc.etl.osdi.processtree.scala.fold.Main"

To generate larger data sets for testing:

$ sbt "test:runMain edu.luc.etl.osdi.processtree.scala.fakeps.Main 100000" > data.txt

To run the benchmarks:

$ sbt 'test:runMain edu.luc.etl.osdi.processtree.scala.fakeps.BenchmarkFold'
$ sbt 'test:runMain edu.luc.etl.osdi.processtree.scala.fakeps.BenchmarkArray'
$ sbt 'test:runMain edu.luc.etl.osdi.processtree.scala.mutable.Benchmark -silent'
$ sbt 'test:runMain edu.luc.etl.osdi.processtree.scala.groupby.Benchmark -silent'
$ sbt 'test:runMain edu.luc.etl.osdi.processtree.scala.fold.Benchmark -silent'

On Windows, if you installed [Git](http://git-scm.com/) with the recommended
third option,
*Use Git and optional Unix tools from the Windows Command Prompt*,
third option, *Use Git and optional Unix tools from the Windows Command Prompt*,
then you will have a `ps` command available.
2 changes: 1 addition & 1 deletion src/main/scala/fold/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ trait FoldTreeBuilder extends common.TreeBuilder {
processes.foldLeft(Map.empty: ProcessTree) { (m, p) =>
val ppid = p._2
val children = m.getOrElse(ppid, Vector.empty) :+ p
m.updated(ppid, children)
m + (ppid -> children)
}
}
8 changes: 5 additions & 3 deletions src/test/scala/common/Benchmark.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import org.scalameter.api._
*/
abstract class Benchmark(label: String) extends Bench.LocalTime with TreeBuilder {

val sizes: Gen[Int] = Gen.exponential("processes")(100, 1000000, 10)
val sizes: Gen[Int] = Gen.exponential("processes")(10, 1000000, 10)

val inputs: Gen[Iterator[Process]] = sizes map fakeps.fakePs cached
/** Inputs cached as (immutable) sequences so we can reuse them. */
val inputs: Gen[Seq[Process]] = sizes.map(n => fakeps.fakePs(n).toSeq).cached

performance of label in {
measure method "buildTree" in {
using (inputs) in { ps =>
buildTree(ps)
// need to get a fresh iterator over the cached sequence
buildTree(ps.iterator)
}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/test/scala/fakeps/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ object Main extends App {
System.exit(1)
}

val n = arg.get
val ps = fakePs(arg.get)
println("%-10s %-10s %-10s".format("PID", "PPID", "CMD"))
for ((pid, ppid, cmd) <- ps)
Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/fakeps/benchmarks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.scalameter.api._

abstract class Benchmark(val f: Int => Iterator[(Int, Int)], val label: String) extends Bench.LocalTime {

val sizes: Gen[Int] = Gen.exponential("processes")(10, 1000000, 10)
val sizes: Gen[Int] = Gen.exponential("processes")(10, 100000, 10)

measure method label in {
using (sizes) in { n =>
Expand Down
19 changes: 10 additions & 9 deletions src/test/scala/fakeps/fakeps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ package object fakeps {
* Generates a barebones process tree (ppid -> pid*) of size n
* using an immutable implementation.
*/
def fakePsFoldSlow(n: Int): Iterator[(Int, Int)] = inverseEdges {
def fakePsFoldSlow(n: Int): Iterator[(Int, Int)] = reverseEdges {
(2 to n).foldLeft {
Map(0 -> Seq(1), 1 -> Seq.empty)
} { (ps, nextPid) =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps + (nextPid -> ps.getOrElse(nextPid, Seq.empty), randomPid -> (nextPid +: ps(randomPid)))
ps + (randomPid -> (nextPid +: ps(randomPid)), nextPid -> Seq.empty)
}
}

/**
* Generates a barebones process tree (ppid -> pid*) of size n
* using an immutable implementation.
*/
def fakePsFold(n: Int): Iterator[(Int, Int)] = inverseEdges {
def fakePsFold(n: Int): Iterator[(Int, Int)] = reverseEdges {
(2 to n).foldLeft {
Map(0 -> Seq(1), 1 -> Seq.empty)
} { (ps, nextPid) =>
Expand All @@ -39,7 +39,7 @@ package object fakeps {
* Generates a barebones process tree (ppid -> pid*) of size n
* using a mutable implementation.
*/
def fakePsMutable(n: Int): Iterator[(Int, Int)] = inverseEdges {
def fakePsMutable(n: Int): Iterator[(Int, Int)] = reverseEdges {
val ps = MMap(0 -> ArrayBuffer(1), 1 -> ArrayBuffer.empty[Int])
(2 to n) foreach { nextPid =>
val randomPid = 1 + Random.nextInt(nextPid - 1)
Expand All @@ -57,14 +57,15 @@ package object fakeps {
val ps = ArrayBuffer.fill(n + 1)(ArrayBuffer.empty[Int])
ps(0) += 1
(2 to n) foreach { nextPid =>
ps(1 + Random.nextInt(nextPid - 1)) += nextPid
val randomPid = 1 + Random.nextInt(nextPid - 1)
ps(randomPid) += nextPid
}
for (ppid <- (0 to n).iterator; pid <- ps(ppid).iterator) yield (pid, ppid)
for (ppid <- ps.indices.iterator ; pid <- ps(ppid).iterator) yield (pid, ppid)
}

/** Converts a tree (ppid -> pid*) into an iterator of pid -> ppid edges. */
def inverseEdges(m: Map[Int, Iterable[Int]]): Iterator[(Int, Int)] =
for (ppid <- m.keys.iterator; pid <- m(ppid).iterator) yield (pid, ppid)
def reverseEdges(m: Map[Int, Iterable[Int]]): Iterator[(Int, Int)] =
for (ppid <- m.keys.iterator ; pid <- m(ppid).iterator) yield (pid, ppid)

/** Adds a command string to each pid -> ppid edge. */
def addCmd(i: Iterator[(Int, Int)], s: String): Iterator[Process] =
Expand All @@ -74,5 +75,5 @@ package object fakeps {
def addCmd(i: Iterator[(Int, Int)]): Iterator[Process] = addCmd(i, "Fake Process")

/** Generates the fake ps command output. */
def fakePs(n: Int) = addCmd(fakePsArray(n))
def fakePs(n: Int) = addCmd(fakePsFold(n))
}