Skip to content

Commit

Permalink
Scalameter for java code
Browse files Browse the repository at this point in the history
  • Loading branch information
zabo committed Jun 5, 2014
1 parent 36e8340 commit 27eebee
Show file tree
Hide file tree
Showing 17 changed files with 643 additions and 18 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ tmp*
.settings

.gitattributes

.metadata/
7 changes: 7 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

name := "scalameter"

organization := "com.github.axel22"

version := "0.9-SNAPSHOT"

2 changes: 1 addition & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
// ```
// This should give you access to the repository.


addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.2.0")
9 changes: 5 additions & 4 deletions src/main/scala/org/scalameter/Gen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ object Gen {
def vectors = for {
size <- sizes
} yield (0 until size).toVector

def arraybuffers = for {
size <- sizes
} yield mutable.ArrayBuffer(0 until size: _*)
Expand All @@ -161,6 +161,7 @@ object Gen {
for (x <- 0 until size) hm(x) = x
hm
}


def linkedhashtablemaps = for {
size <- sizes
Expand All @@ -169,7 +170,7 @@ object Gen {
for (x <- 0 until size) hm(x) = x
hm
}

def hashtriemaps = for {
size <- sizes
} yield {
Expand All @@ -195,15 +196,15 @@ object Gen {
for (x <- 0 until size) hs.add(x)
hs
}

def linkedhashtablesets = for {
size <- sizes
} yield {
val hs = mutable.LinkedHashSet[Int]()
for (x <- 0 until size) hs.add(x)
hs
}

def avlsets = for {
size <- sizes
} yield {
Expand Down
288 changes: 288 additions & 0 deletions src/main/scala/org/scalameter/JavaPerformanceTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
package org.scalameter
import org.scalameter.execution.LocalExecutor
import org.scalameter.Executor.Measurer
import org.scalameter.reporting.LoggingReporter
import utils.Tree
import java.util.Date
import scala.util.DynamicVariable
import java.util.Arrays
import java.util.HashMap
import Key._
import org.scalameter.javaApi.JavaGenerator
import scala.collection.JavaConverters._
import scala.collection.mutable.ArrayBuffer

abstract class JavaPerformanceTest extends DSL with DelayedInit {

//usefull for match on class interface
val Group = classOf[org.scalameter.javaApi.Group]
val UsingInterface = classOf[org.scalameter.javaApi.Using[java.lang.Object, java.lang.Object]]
def defaultConfig: Context = Context.empty

def executor: Executor = javaExecutor.get
def measurer: Measurer = javaMeasurer.get
def reporter: Reporter = javaReporter.get
def persistor = javaPersistor.get

def javaExecutor: org.scalameter.javaApi.Executor
def javaMeasurer: org.scalameter.javaApi.Measurer
def javaPersistor: org.scalameter.javaApi.Persistor
def javaReporter: org.scalameter.javaApi.Reporter
type SameType

constructScope(this.getClass)

def getClassInstance(s: String): Object = {
val clss = Class.forName(s)
var outerClasses = clss.getEnclosingClass()
if (outerClasses == null) {
Class.forName(s).newInstance.asInstanceOf[Object]
} else {
val obj = getClassInstance(outerClasses.getName)
val c = Class.forName(s).getDeclaredConstructors()(0)
c.newInstance(obj.asInstanceOf[Object]).asInstanceOf[Object]
}
}

def config(c: Class[_]): List[KeyValue] = {
val methods = c.getMethods
val instance = getClassInstance(c.getName)
for (m <- methods) {
if (m.getName.equals("config")) {
val config = m.invoke(instance).asInstanceOf[HashMap[javaApi.exec, Any]]
val keys = config.keySet
var kv: List[KeyValue] = List()
for (k <- keys.toArray) {
k match {
case javaApi.exec.benchRuns => {
config.get(k) match {
case d: Double => kv = (exec.benchRuns -> d.toInt) :: kv
case i: Int => kv = (exec.benchRuns -> i) :: kv
case _ =>
}
}
case javaApi.exec.independentSamples => {
config.get(k) match {
case d: Double => kv = (exec.independentSamples -> d.toInt) :: kv
case i: Int => kv = (exec.independentSamples -> i) :: kv
case _ =>
}
}
case javaApi.exec.maxWarmupRuns => {
config.get(k) match {
case d: Double => kv = (exec.maxWarmupRuns -> d.toInt) :: kv
case i: Int => kv = (exec.maxWarmupRuns -> i) :: kv
case _ =>
}
}
case javaApi.exec.minWarmupRuns => {
config.get(k) match {
case d: Double => kv = (exec.minWarmupRuns -> d.toInt) :: kv
case i: Int => kv = (exec.minWarmupRuns -> i) :: kv
case _ =>
}
}
case javaApi.exec.warmupCovThreshold => {
config.get(k) match {
case d: Double => kv = (exec.warmupCovThreshold -> d) :: kv
case i: Int => kv = (exec.warmupCovThreshold -> i.toDouble) :: kv
case _ =>
}
}
case javaApi.exec.jvmflags => {
config.get(k) match {
case s: String => kv = (exec.jvmflags -> s) :: kv
case _ =>
}
}
case javaApi.exec.jvmcmd => config.get(k) match {
case s: String => kv = (exec.jvmcmd -> s) :: kv
case _ =>
}
case _ =>
}
}
return kv
}
}
return List()
}

def constructScope(c: Class[_]): Unit = {
for (clzz <- c.getClasses()) {
classScope(clzz)
}
}

def classScope(c: Class[_]): Unit = {
val cl = c.getInterfaces
if (!cl.isEmpty) {
cl.head match {
case Group => {
val classGroupName = c.getName
var s = Scope(classGroupName, DSL.setupzipper.value.current.context)
val configuration = config(c)
if (!configuration.isEmpty) {

s = s.config(configuration: _*)
}

val oldscope = s.context(Key.dsl.scope)

val ct = s.context + (Key.dsl.scope -> (c.getSimpleName() :: oldscope))
DSL.setupzipper.value = DSL.setupzipper.value.descend.setContext(ct)
for (clzz <- c.getClasses) classScope(clzz)
DSL.setupzipper.value = DSL.setupzipper.value.ascend
}

case UsingInterface => {
val classGroupName = c.getName
var s = Scope(classGroupName, DSL.setupzipper.value.current.context)
val configuration = config(c)
if (!configuration.isEmpty)
s = s.config(configuration: _*)

val oldscope = s.context(Key.dsl.scope)

val method = c.getMethod("snippet", classOf[Object])
val context = DSL.setupzipper.value.current.context + (Key.dsl.scope -> (c.getSimpleName() :: oldscope))
DSL.setupzipper.value = DSL.setupzipper.value.descend.setContext(context)

val instance = getClassInstance(c.getName)
var setupbeforeall: Option[() => Unit] = None
var teardownafterall: Option[() => Unit] = None
var setp: Option[Object => Any] = None
var teardown: Option[Object => Any] = None
val gen = c.getMethod("generator").invoke(instance).asInstanceOf[JavaGenerator[Any]]
for (m <- c.getMethods) {
m.getName match {
case "beforeTests" => {
setupbeforeall = Some(() => { m.invoke(instance) })
}
case "afterTests" => teardownafterall = Some(() => { m.invoke(instance) })
case "setup" => {
if (classOf[org.scalameter.javaApi.VoidGen] isAssignableFrom gen.getClass) {
setp = Some((v: Object) => { m.invoke(instance, null) })
} else {
setp = Some((v: Object) => { m.invoke(instance, v) })
}
}
case "teardown" => {
if (classOf[org.scalameter.javaApi.VoidGen] isAssignableFrom gen.getClass) {
teardown = Some((v: Object) => { m.invoke(instance, null) })
} else {
teardown = Some((v: Object) => { m.invoke(instance, v) })
}
}
case _ =>
}
}
var snippet = (s: Object) => { method.invoke(instance, s) }
if (classOf[org.scalameter.javaApi.VoidGen] isAssignableFrom gen.getClass) {
snippet = (s: Object) => { method.invoke(instance, null) }
}
val generator = gen.get

val setup = Setup(context, generator.asInstanceOf[Gen[Object]], setupbeforeall, teardownafterall, setp, teardown, None, snippet, executor)
DSL.setupzipper.value = DSL.setupzipper.value.addItem(setup)
DSL.setupzipper.value = DSL.setupzipper.value.ascend
}

case _ =>
}
}
}

// copy/paste from PerformanceTest
def executeTests(): Boolean = {
val datestart: Option[Date] = Some(new Date)
DSL.setupzipper.value = Tree.Zipper.root[Setup[_]].modifyContext(_ ++ defaultConfig)
testbody.value.apply()
val rawsetuptree = DSL.setupzipper.value.result
val setuptree = rawsetuptree.filter(setupFilter)
val resulttree = executor.run(setuptree.asInstanceOf[Tree[Setup[SameType]]], reporter, persistor)
val dateend: Option[Date] = Some(new Date)
val datedtree = resulttree.copy(context = resulttree.context + (Key.reports.startDate -> datestart) + (Key.reports.endDate -> dateend))
reporter.report(datedtree, persistor)
}

def delayedInit(body: => Unit) {
val current = testbody.value
testbody.value = () => { current(); body }
testbodySet = true
}
private def setupFilter(setup: Setup[_]): Boolean = {
val sf = initialContext(Key.scopeFilter)
val fullname = setup.context.scope + "." + setup.context.curve
val regex = sf.r
regex.findFirstIn(fullname) != None
}

}

abstract class QuickBenchmark extends JavaPerformanceTest {
def javaReporter = new org.scalameter.javaApi.LoggingReporter

def javaPersistor = new org.scalameter.javaApi.NonePersistor

def javaExecutor: org.scalameter.javaApi.Executor = new org.scalameter.javaApi.LocalExecutor(
new org.scalameter.Executor.Warmer.Default(),
new org.scalameter.javaApi.MinAggregator,
new org.scalameter.javaApi.DefaultMeasurer)
def javaMeasurer: org.scalameter.javaApi.Measurer = new org.scalameter.javaApi.DefaultMeasurer
}

abstract class Microbenchmark extends JavaPerformanceTest {
import Executor.Measurer
def warmer = org.scalameter.Executor.Warmer.Default()
def aggregator = Aggregator.min
override def measurer = new Measurer.IgnoringGC with Measurer.PeriodicReinstantiation {
override val defaultFrequency = 12
override val defaultFullGC = true
}
def javaMeasurer = ???
override def executor = execution.SeparateJvmsExecutor(warmer, aggregator, measurer)
def javaExecutor = ???
def javaReporter = new org.scalameter.javaApi.LoggingReporter
def javaPersistor = new org.scalameter.javaApi.NonePersistor
}

abstract class HTMLReport extends JavaPerformanceTest {
import Executor.Measurer
import reporting._
def javaPersistor = new org.scalameter.javaApi.SerializationPersistor
def warmer = Executor.Warmer.Default()
def aggregator = Aggregator.average
override def measurer: Measurer = new Measurer.IgnoringGC with Measurer.PeriodicReinstantiation with Measurer.OutlierElimination with Measurer.RelativeNoise
def javaMeasurer = ???
override def executor: Executor = new execution.SeparateJvmsExecutor(warmer, aggregator, measurer)
def javaExecutor = ???

def tester: RegressionReporter.Tester = javaTester.get
def historian: RegressionReporter.Historian = javaHistorian.get
def online: Boolean
def javaTester: org.scalameter.javaApi.RegressionReporterTester
def javaHistorian: org.scalameter.javaApi.RegressionReporterHistorian
def javaReporter = new org.scalameter.javaApi.CompositeReporter(tester, historian, online)
}

abstract class OnlineRegressionReport extends HTMLReport {
import reporting._
def javaTester = new org.scalameter.javaApi.OverlapIntervals()
def javaHistorian = new org.scalameter.javaApi.ExponentialBackoff()
def online = true
}

abstract class OfflineRegressionReport extends HTMLReport {
import reporting._
def javaTester = new org.scalameter.javaApi.OverlapIntervals()
def javaHistorian = new org.scalameter.javaApi.ExponentialBackoff()
def online = false
}

abstract class OfflineReport extends HTMLReport {
import reporting._
def javaTester = new org.scalameter.javaApi.Accepter()
def javaHistorian = new org.scalameter.javaApi.ExponentialBackoff()
def online = false
}
3 changes: 1 addition & 2 deletions src/main/scala/org/scalameter/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ object Main {
// identify test objects
dyn.currentContext.withValue(Context.topLevel ++ configuration.context) {
import configuration._

// schedule benchmarks
val testResults = for (benchname <- benches) yield {
val bench = Class.forName(benchname).newInstance.asInstanceOf[PerformanceTest]
val bench = Class.forName(benchname).newInstance.asInstanceOf[DSL]
bench.executeTests()
}

Expand Down
9 changes: 3 additions & 6 deletions src/main/scala/org/scalameter/PerformanceTest.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package org.scalameter



import collection._
import utils.Tree
import java.util.Date

import scala.collection._
import utils.Tree

abstract class PerformanceTest extends PerformanceTest.Initialization with Serializable {

Expand Down Expand Up @@ -56,7 +53,7 @@ object PerformanceTest {
val regex = sf.r
regex.findFirstIn(fullname) != None
}

/** Quick benchmark run in the same JVM.
* Reports result into the console.
*/
Expand Down
Loading

0 comments on commit 27eebee

Please sign in to comment.