Skip to content

Remove Bench or A generic JHM benchmark interface #2884

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

Merged
merged 2 commits into from
Jul 25, 2017
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
73 changes: 73 additions & 0 deletions bench/src/main/scala/Benchmarks.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package dotty.tools.benchmarks

import dotty.tools.dotc._
import core.Contexts.Context

import org.openjdk.jmh.results.RunResult
import org.openjdk.jmh.runner.Runner
import org.openjdk.jmh.runner.options.OptionsBuilder
import org.openjdk.jmh.annotations._
import org.openjdk.jmh.results.format._
import java.util.concurrent.TimeUnit

import java.io.{File, FileOutputStream, BufferedWriter, FileWriter}
import scala.collection.JavaConversions._
import scala.io.Source

object Bench {
val COMPILE_OPTS_FILE = "compile.txt"

def main(args: Array[String]): Unit = {
storeCompileOptions(args)

val libs = System.getenv("BOOTSTRAP_APPEND")

val opts = new OptionsBuilder()
.jvmArgsPrepend(s"-Xbootclasspath/a:$libs")
.mode(Mode.AverageTime)
.timeUnit(TimeUnit.MICROSECONDS)
.forks(5)
.warmupIterations(5)
.measurementIterations(10)
.resultFormat(ResultFormatType.CSV)
.result("result.csv")
.build

val runner = new Runner(opts) // full access to all JMH features, you can also provide a custom output Format here
runner.run() // actually run the benchmarks

removeCompileOptions
}

def removeCompileOptions: Unit = new File(COMPILE_OPTS_FILE).delete()

def storeCompileOptions(args: Array[String]): Unit = {
val file = new File(COMPILE_OPTS_FILE)
val bw = new BufferedWriter(new FileWriter(file))
bw.write(args.mkString("\n"))
bw.close()
}

def readCompileOptions: Seq[String] =
Source.fromFile(COMPILE_OPTS_FILE).getLines.toSeq
}

@State(Scope.Benchmark)
class CompilerOptions {
var opts: Array[String] = null

@Setup
def prepare: Unit = {
opts = Bench.readCompileOptions.to[Array]
}
}

class Worker extends Driver {
override def newCompiler(implicit ctx: Context): Compiler = new Compiler

@Benchmark
def compile(state: CompilerOptions): Unit = {
val res = process(state.opts)
if (res.hasErrors) throw new Exception("compilation failed")
}
}
147 changes: 147 additions & 0 deletions bench/templates/launch.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
#!/bin/sh
#/*--------------------------------------------------------------------------
# * Copyright 2012 Taro L. Saito
# *
# * Licensed under the Apache License, Version 2.0 (the "License");
# * you may not use this file except in compliance with the License.
# * You may obtain a copy of the License at
# *
# * http://www.apache.org/licenses/LICENSE-2.0
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
# *--------------------------------------------------------------------------*/

if [ -z "$PROG_HOME" ] ; then
## resolve links - $0 may be a link to PROG_HOME
PRG="$0"

# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done

saveddir=`pwd`

PROG_HOME=`dirname "$PRG"`/..

# make it fully qualified
PROG_HOME=`cd "$PROG_HOME" && pwd`

cd "$saveddir"
fi


cygwin=false
mingw=false
darwin=false
case "`uname`" in
CYGWIN*) cygwin=true
;;
MINGW*) mingw=true
;;
Darwin*) darwin=true
if [ -z "$JAVA_VERSION" ] ; then
JAVA_VERSION="CurrentJDK"
else
echo "Using Java version: $JAVA_VERSION" 1>&2
fi
if [ -z "$JAVA_HOME" ] ; then
JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/${JAVA_VERSION}/Home
fi
JAVACMD="`which java`"
;;
esac

# Resolve JAVA_HOME from javac command path
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" -a -f "$javaExecutable" -a ! "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
javaExecutable="`readlink -f \"$javaExecutable\"`"
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi


if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi

if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly."
echo " We cannot execute $JAVACMD"
exit 1
fi

if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi

CLASSPATH_SUFFIX=""
# Path separator used in EXTRA_CLASSPATH
PSEP=":"

# For Cygwin, switch paths to Windows-mixed format before running java
if $cygwin; then
[ -n "$PROG_HOME" ] &&
PROG_HOME=`cygpath -am "$PROG_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath -am "$JAVA_HOME"`
CLASSPATH_SUFFIX=";"
PSEP=";"
fi

# For Migwn, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$PROG_HOME" ] &&
PROG_HOME="`(cd "$PROG_HOME"; pwd -W | sed 's|/|\\\\|g')`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd -W | sed 's|/|\\\\|g')`"
CLASSPATH_SUFFIX=";"
PSEP=";"
fi


PROG_NAME={{{PROG_NAME}}}
PROG_VERSION={{{PROG_VERSION}}}
PROG_REVISION={{{PROG_REVISION}}}

# add default libraries for compilation
export BOOTSTRAP_APPEND="{{{EXPANDED_CLASSPATH}}}${CLASSPATH_SUFFIX}"

eval exec "\"$JAVACMD\"" \
{{{JVM_OPTS}}} \
${JAVA_OPTS} \
{{^EXPANDED_CLASSPATH}}
-cp "'{{{EXTRA_CLASSPATH}}}${PROG_HOME}/lib/*${CLASSPATH_SUFFIX}'" \
{{/EXPANDED_CLASSPATH}}
{{#EXPANDED_CLASSPATH}}
-cp "'{{{EXTRA_CLASSPATH}}}{{{EXPANDED_CLASSPATH}}}${CLASSPATH_SUFFIX}'" \
{{/EXPANDED_CLASSPATH}}
{{{MAIN_CLASS}}} \"\$@\"
exit $?
108 changes: 0 additions & 108 deletions bench/test/dotty/tools/benchmarks/Benchmarks.scala

This file was deleted.

48 changes: 14 additions & 34 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import dotty.tools.sbtplugin.DottyIDEPlugin.autoImport._
import org.scalajs.sbtplugin.ScalaJSPlugin
import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._

import pl.project13.scala.sbt.JmhPlugin
import JmhPlugin.JmhKeys.Jmh

/* In sbt 0.13 the Build trait would expose all vals to the shell, where you
* can use them in "set a := b" like expressions. This re-exposes them.
*/
Expand Down Expand Up @@ -822,42 +825,19 @@ object Build {
)))

lazy val `dotty-bench` = project.in(file("bench")).
dependsOn(`dotty-compiler` % "compile->test").
dependsOn(`dotty-compiler`).
settings(commonNonBootstrappedSettings).
settings(
baseDirectory in (Test,run) := (baseDirectory in `dotty-compiler`).value,

libraryDependencies += "com.storm-enroute" %% "scalameter" % "0.6" % Test,

fork in Test := true,
parallelExecution in Test := false,

// http://grokbase.com/t/gg/simple-build-tool/135ke5y90p/sbt-setting-jvm-boot-paramaters-for-scala
javaOptions ++= {
val attList = (dependencyClasspath in Runtime).value
val bin = (packageBin in Compile).value

// put the Scala {library, reflect, compiler} in the classpath
val path = for {
file <- attList.map(_.data)
path = file.getAbsolutePath
prefix = if (path.endsWith(".jar")) "p" else "a"
} yield "-Xbootclasspath/" + prefix + ":" + path
// dotty itself needs to be in the bootclasspath
val fullpath = ("-Xbootclasspath/a:" + bin) :: path.toList
// System.err.println("BOOTPATH: " + fullpath)

val ci_build = // propagate if this is a ci build
if (sys.props.isDefinedAt(JENKINS_BUILD))
List(s"-D$JENKINS_BUILD=${sys.props(JENKINS_BUILD)}")
else if (sys.props.isDefinedAt(DRONE_MEM))
List("-Xmx" + sys.props(DRONE_MEM))
else
List()
val res = agentOptions ::: ci_build ::: fullpath
println("Running with javaOptions: " + res)
res
}
mainClass in (Jmh, run) := Some("dotty.tools.benchmarks.Bench") // custom main for jmh:run
).
enablePlugins(JmhPlugin).
settings(packSettings).
settings(
publishArtifact := false,
packMain := Map("bench" -> "dotty.tools.benchmarks.Bench"),
packGenerateWindowsBatFile := false,
packExpandedClasspath := true,
packBashTemplate := baseDirectory.value + "/templates/launch.mustache"
)

// Depend on dotty-library so that sbt projects using dotty automatically
Expand Down
Loading