summaryrefslogtreecommitdiff
path: root/test/benchmarks/src/scala/collection/parallel/benchmarks/Bench.scala
blob: c20bbaeef1fb73e54d401ae7073011e6cb042c76 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package scala.collection.parallel.benchmarks


import scala.collection._
import scala.testing.Benchmark



trait BenchCompanion {
  def benchName: String
  def collectionName: String
  def fullname = collectionName + "." + benchName
  def defaultSize = 100000
  def comparisons = List[String]()
  def apply(sz: Int, parallelism: Int, what: String): Bench
}


/**
 * An interface for all benchmark classes.
 * A benchmark runs some functionality a prespecified number of times.
 */
trait Bench extends Benchmark {
  val size: Int
  
  val parallelism: Int
  
  val runWhat: String
  
  /**
   * Name of the benchmark. Convention is for it to start with the name of the collection being
   * tested, continuing '.' and ending with the name of the specific functionality being benchmarked. 
   * @return
   */
  def name: String = companion.fullname
  def collectionName: String = companion.collectionName
  def benchName: String = companion.benchName
  
  def companion: BenchCompanion
  
  def runseq: Unit
  
  def runpar: Unit
  
  /**
   * Describes the number of runs of the test.
   */
  val runs = 10
  
  /**
   * Returns the number of repetitions for this benchmark.
   */
  def repetitionsPerRun = 500
  
  /**
   * Resets the benchmark object. Typically, this means recreating
   * the collection being tested.
   */
  def reset: Unit
  
  /**
   * Returns a map of available comparison tests.
   */
  def comparisons: List[String] = companion.comparisons
  
  def comparison(name: String): Option[() => Unit] = comparisonMap.get(name)
  
  def comparisonMap: Map[String, () => Unit]
  
  def run = runWhat match {
    case "seq" => for (i <- 0 until repetitionsPerRun) runseq
    case "par" => for (i <- 0 until repetitionsPerRun) runpar
    case _ => comparison(runWhat) match {
      case Some(fun) => for (i <- 0 until repetitionsPerRun) fun()
      case None => throw new IllegalArgumentException("Unknown bench option: `" + runWhat + 
          "`, need `seq`, `par` or one of: " + comparisons.mkString("`", "`, `", "`"))
    }
  }
  
  /**
   * Prints results of the benchmark. May be overridden in benchmarks.
   */
  def printResults {}
  
  def onEnd {}
  
  def executeBenchmark = {
    println("-----------------------")
    print(name + ", " + runWhat + ", par.=" + parallelism + ", sz=" + niceSize + ": ")
    
    val times = runBenchmark(runs)
    
    onEnd
    
    for (t <- times) print(t + " ")
    println
    printResults
  }
  
  private def niceSize = if (size < 1000 || size % 1000 != 0) size.toString else size / 1000 + "k"
}


trait HavingResult[T] extends Bench {
  var runresult: T = null.asInstanceOf[T]
  
  abstract override def printResults {
    println("result: " + (if (runresult != null) runresult else "<not set>"))
    super.printResults
  }
}