1+ /*
2+ * Copyright (c) 2012 Dragos Manolescu.
3+ *
4+ * Published under the Apache 2.0 license; see http://www.apache.org/licenses/LICENSE-2.0.html
5+ */
16package com .microWorkflow .jsonScalaPerftest
27
3- import java .io .File
4- import io .Source
5- import com .yammer .metrics .reporting .CsvReporter
6- import java .util .concurrent .TimeUnit
7- import fr .janalyse .jmx .JMX
8- import com .yammer .metrics .Metrics
8+ import collection .immutable .HashMap
99
10- case class Dataset (fileName : String , name : String ) {
11-
12- def this (fn : String ) = {
13- this (fn, fn.substring(fn.lastIndexOf('/' ) + 1 , fn.lastIndexOf('.' )))
14- }
15-
16- val docs : List [String ] = Source .fromFile(fileName).getLines().toList
17-
18- override def toString = {
19- val sb = new StringBuilder
20- sb.append(name)
21- sb.append(" (" )
22- sb.append(docs.length)
23- sb.append(" documents)" )
24- sb.toString()
25- }
26- }
27-
28- case class Category (directoryName : String , name : String ) {
29-
30- def this (fn : String ) = {
31- this (fn, fn.substring(fn.lastIndexOf('/' ) + 1 ))
32- }
33-
34- val datasets = Category .getFilesMatching(directoryName, fn => fn.isFile).map {
35- each => new Dataset (each.getCanonicalPath)
36- }
37-
38- override def toString = {
39- val sb = new StringBuilder
40- sb.append(name)
41- sb.append(datasets.map(ds => ds.toString).mkString(" : " , " , " , " " ))
42- sb.toString()
43- }
44-
45- def measure (adapter : LibraryAdaptor , doMap : Boolean ) {
46- for (dataset <- datasets) {
47- adapter.measure(dataset, doMap)
48- }
49- }
50- }
51-
52- object Category {
53- def getFilesMatching (path : String , p : File => Boolean ) = {
54- val dir = new java.io.File (path).getAbsolutePath
55- new File (dir).listFiles.filter(file => p(file))
56- }
57- }
58-
59-
60- case class Experiment (measurementsPath : String ) {
10+ case class Experiment (warmUpIterations : Int = 5 ) {
6111
6212 val adapters = Array (new liftjson.LiftJsonAdaptor (" lift" )
6313 , new jerkson.JerksonAdaptor (" jerkson" )
@@ -70,62 +20,65 @@ case class Experiment(measurementsPath: String) {
7020 , new jackson.JacksonAdaptor (" jackson" )
7121 )
7222
73- val loopCounter = Metrics .newCounter( this .getClass, " main loop " )
74-
75- val categories = Category .getFilesMatching( " data " , f => f.isDirectory) .map(d => new Category (d.getCanonicalPath))
23+ val categories = Category
24+ .getFilesMatching( " data " , f => f.isDirectory)
25+ .map(d => new Category (d.getCanonicalPath))
7626
77- def run (iterations : Int , doMap : Boolean ) = {
78- loopCounter.clear()
79- val oldFiles = Category .getFilesMatching(measurementsPath, f => f.isFile)
80- println(" Removing %d old files" .format(oldFiles.length))
81- if (oldFiles != null )
82- oldFiles.foreach(f => f.delete())
83- CsvReporter .enable(new File (measurementsPath), 100 , TimeUnit .MILLISECONDS )
27+ def run (iterations : Int , doMap : Boolean ): Array [(String , HashMap [String , Measurement ])] = {
8428 val adaptersToTest = if (doMap) adapters.filter(_.hasMap) else adapters
85- for (count <- 1 to iterations) {
86- categories.flatMap(c => (adaptersToTest.map {
87- each => c.measure(each, doMap)
88- }))
89- loopCounter.inc()
90- }
29+ categories.flatMap(c => (adaptersToTest.map {
30+ each => (c.name -> c.measure(each, doMap, iterations))
31+ }))
9132 }
9233
93- def takeMeasurements (iterations : Int , doMap : Boolean ) {
94- val where = new File (measurementsPath)
95- where.mkdirs()
96- print(" Priming caches..." )
97- run(iterations, doMap)
98- print(" Measuring timings..." )
34+ def takeMeasurements (iterations : Int , doMap : Boolean ): Array [(String , HashMap [String , Measurement ])] = {
35+ println(" Warming up (%d iterations)..." .format(warmUpIterations))
36+ run(warmUpIterations, doMap)
37+ println(" Measuring (%d iterations)..." .format(iterations))
9938 run(iterations, doMap)
10039 }
101-
102- def printMeanValues () {
103- JMX .once() {
104- jmx => {
105- val beans = jmx.mbeans().filter(b => b.name.contains(" microWorkflow" .toCharArray))
106- for (bean <- beans) {
107- val mean = bean.getDouble(" Mean" ) match {
108- case Some (d) => d
109- case None => 0.0
110- }
111- println(" %s: %fms" .format(bean.name.substring(bean.name.indexOf('=' ) + 1 ), mean))
112- }
113- }
114- }
115- }
11640}
11741
11842
11943object Main {
44+ val usage =
45+ """
46+ |Usage: com.microWorkflow.jsonScalaPerftest.Main [-n num] [-w num] [-map]
47+ """ .stripMargin
12048
12149 def main (args : Array [String ]) {
122- val where = if (args.length> 0 ) args(0 ) else " /tmp/measurements"
123- val iterations : Int = if (args.length> 1 ) args(1 ).toInt else 100
124- val doMap = if (args.length> 2 ) args(2 ).equalsIgnoreCase(" -map" ) else false
125- println(" Runing %d iterations %s object mapping; test results in %s"
126- .format(iterations, if (doMap) " with" else " without" , where))
127- val e = Experiment (where)
128- e.takeMeasurements(iterations, doMap)
129- println(" Done" )
50+ if (args.isEmpty) println(usage)
51+ else {
52+
53+ def nextOption (map : Map [Symbol , Any ], list : List [String ]): Map [Symbol , Any ] = {
54+ list match {
55+ case Nil => map
56+ case " -n" :: value :: tail => nextOption(map + (' iterations -> value.toInt), tail)
57+ case " -w" :: value :: tail => nextOption(map + (' warmUp -> value.toInt), tail)
58+ case " -map" :: tail => nextOption(map + (' map -> true ), tail)
59+ case _ :: tail =>
60+ println(" Don't know what to do with '%s'%s" .format(list.head, usage))
61+ sys.exit(1 )
62+ }
63+ }
64+ val options = nextOption(new HashMap [Symbol , Any ](), args.toList)
65+
66+ val iterations = options.getOrElse(' iterations , 100 ).asInstanceOf [Int ]
67+ val doMap = options.getOrElse(' map , false ).asInstanceOf [Boolean ]
68+ val warmUpIterations = options.getOrElse(' warmUp , 5 ).asInstanceOf [Int ]
69+
70+ println(" Runing %d iterations %s object mapping"
71+ .format(iterations, if (doMap) " with" else " without" ))
72+ val experiment = Experiment (warmUpIterations)
73+ val ms = experiment.takeMeasurements(iterations, doMap)
74+ for (m <- ms) {
75+ print(" Category: %s\n " .format(m._1))
76+ for (d <- m._2.iterator)
77+ print(" \t dataset '%s', measurement: %s\n " .format(d._1, d._2))
78+ }
79+
80+ sys.exit()
81+ }
82+
13083 }
13184}
0 commit comments