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

Benchmarks #65

Merged
merged 1 commit into from Feb 15, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 39 additions & 0 deletions benchmarks/src/main/scala/org/scalafmt/FormatBenchmark.scala
@@ -0,0 +1,39 @@
package org.scalafmt

import scala.meta.Source
import scalariform.formatter.preferences._
import scalariform.formatter.ScalaFormatter


import java.util.concurrent.TimeUnit

import org.openjdk.jmh.annotations.Measurement
import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.BenchmarkMode
import org.openjdk.jmh.annotations.Benchmark
import org.openjdk.jmh.annotations.OutputTimeUnit
import org.openjdk.jmh.annotations.Mode
import org.openjdk.jmh.annotations.Warmup

@org.openjdk.jmh.annotations.State(Scope.Benchmark)
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@BenchmarkMode(Array(Mode.AverageTime))
@OutputTimeUnit(TimeUnit.NANOSECONDS)
class FormatBenchmark {
val tests = UnitTests.tests.map(_.original).toArray

val fmt = new ScalaFmt(Standard)

val preferences = FormattingPreferences().setPreference(IndentSpaces, 3)

@Benchmark
def scalafmt(): Unit = {
tests.foreach(x => fmt.format_![Source](x, None)(scala.meta.parsers.parseSource))
}

@Benchmark
def scalariform(): Unit = {
tests.foreach(ScalaFormatter.format(_, preferences))
}
}
60 changes: 45 additions & 15 deletions build.sbt
Expand Up @@ -76,18 +76,13 @@ lazy val root = project.in(file("."))
.settings(
initialCommands in console :=
"""
|import io.finch.{Endpoint => _, _}
|import io.finch.argonaut._
|import io.finch.request._
|import io.finch.request.items._
|import io.finch.response._
|import io.finch.route._
|import org.scalafmt._
""".stripMargin
)
.aggregate(core)
).aggregate(core, tests, benchmarks)
.dependsOn(core)

lazy val core = project.in(file("core"))

lazy val core = project
.settings(allSettings)
.settings(
moduleName := "scalafmt-core",
Expand All @@ -98,12 +93,47 @@ lazy val core = project.in(file("core"))
"com.typesafe.scala-logging" %% "scala-logging" % "3.1.0",
"ch.qos.logback" % "logback-classic" % "1.1.3",
"org.scalameta" %% "scalameta" % "0.0.5-M1",
"com.lihaoyi" %% "sourcecode" % "0.1.0",
"com.ibm" %% "couchdb-scala" % "0.6.0" % "test",
"com.googlecode.java-diff-utils" % "diffutils" % "1.3.0" % "test",
"com.lihaoyi" %% "scalatags" % "0.5.4" % "test",
"org.apache.commons" % "commons-math3" % "3.6" % "test",
"org.scalatest" %% "scalatest" % "2.2.1" % "test"
"com.lihaoyi" %% "sourcecode" % "0.1.0"
)
).settings(allSettings)

lazy val tests = project
.settings(allSettings)
.settings(
moduleName := "scalafmt-tests",
libraryDependencies ++= Seq(
"com.ibm" %% "couchdb-scala" % "0.6.0",
"com.googlecode.java-diff-utils" % "diffutils" % "1.3.0",
"com.lihaoyi" %% "scalatags" % "0.5.4",
"org.apache.commons" % "commons-math3" % "3.6",
"org.scalatest" %% "scalatest" % "2.2.1" % "test"
)
).dependsOn(core)

lazy val benchmarks = project
.settings(moduleName := "scalafmt-benchmarks")
.settings(allSettings)
.settings(
libraryDependencies ++= Seq(
"org.scalariform" %% "scalariform" % "0.1.8"
),
javaOptions in run ++= Seq(
"-Djava.net.preferIPv4Stack=true",
"-XX:+AggressiveOpts",
"-XX:+UseParNewGC",
"-XX:+UseConcMarkSweepGC",
"-XX:+CMSParallelRemarkEnabled",
"-XX:+CMSClassUnloadingEnabled",
"-XX:ReservedCodeCacheSize=128m",
"-XX:MaxPermSize=1024m",
"-Xss8M",
"-Xms512M",
"-XX:SurvivorRatio=128",
"-XX:MaxTenuringThreshold=0",
"-Xss8M",
"-Xms512M",
"-Xmx2G",
"-server"
)
).dependsOn(core, tests)
.enablePlugins(JmhPlugin)
13 changes: 0 additions & 13 deletions core/src/main/scala/org/scalafmt/Benchmark.scala

This file was deleted.

2 changes: 0 additions & 2 deletions core/src/test/scala/org/scalafmt/Benchmark.scala

This file was deleted.

7 changes: 7 additions & 0 deletions tests/src/main/scala/org/scalafmt/DiffTest.scala
@@ -0,0 +1,7 @@
package org.scalafmt

case class DiffTest(spec: String, name: String, filename: String,
original: String, expected: String, skip: Boolean, only: Boolean,
style: ScalaStyle) {
val fullName = s"$spec: $name"
}
Expand Up @@ -4,9 +4,9 @@ object FilesUtil {

def listFiles(path: String): Vector[String] = {

def listFilesIter(s: java.io.File): Iterator[String] = {
def listFilesIter(s: java.io.File): Iterable[String] = {
val (dirs, files) =
Option(s.listFiles()).toIterator.flatMap(_.toIterator)
Option(s.listFiles()).toIterable.flatMap(_.toIterator)
.partition(_.isDirectory)
files.map(_.getPath) ++ dirs.flatMap(listFilesIter)
}
Expand All @@ -24,4 +24,4 @@ object FilesUtil {
val path = java.nio.file.Paths.get(filename)
java.nio.file.Files.write(path, content.getBytes)
}
}
}
3 changes: 3 additions & 0 deletions tests/src/main/scala/org/scalafmt/FormatOutput.scala
@@ -0,0 +1,3 @@
package org.scalafmt

case class FormatOutput(token: String, whitespace: String, visits: Int)
27 changes: 27 additions & 0 deletions tests/src/main/scala/org/scalafmt/HasTests.scala
@@ -0,0 +1,27 @@
package org.scalafmt

import scala.meta.Tree
import scala.meta.parsers.common.Parse

trait HasTests {
val testDir = "tests/src/test/resources"

def isOnly(name: String) = name.startsWith("ONLY ")

def isSkip(name: String) = name.startsWith("SKIP ")

def stripPrefix(name: String) =
name.stripPrefix("SKIP ").stripPrefix("ONLY ").trim

def filename2parse(filename: String): Option[Parse[_ <: Tree]] =
extension(filename) match {
case "source" | "scala" => Some(scala.meta.parsers.parseSource)
case "stat" => Some(scala.meta.parsers.parseStat)
case "case" => Some(scala.meta.parsers.parseCase)
case _ => None
}

def extension(filename: String): String = filename.replaceAll(".*\\.", "")

def tests: Seq[DiffTest]
}
14 changes: 14 additions & 0 deletions tests/src/main/scala/org/scalafmt/Result.scala
@@ -0,0 +1,14 @@
package org.scalafmt

import java.util.concurrent.TimeUnit

case class Result(test: DiffTest, obtained: String, obtainedHtml: String,
tokens: Seq[FormatOutput], maxVisitsOnSingleToken: Int, visitedStates: Int,
timeNs: Long) {

def title = f"${test.name} (${timeMs}ms, $visitedStates states)"

def statesPerMs: Long = visitedStates / timeMs

def timeMs = TimeUnit.MILLISECONDS.convert(timeNs, TimeUnit.NANOSECONDS)
}
@@ -1,8 +1,8 @@
package org.scalafmt

object UnitTests extends HasTests with ScalaFmtLogger {
import FilesUtil._
override lazy val tests: Seq[DiffTest] = {
import FilesUtil._
for {
filename <- listFiles(testDir)
if filename2parse(filename).isDefined
Expand Down
File renamed without changes.
Expand Up @@ -20,47 +20,8 @@ import scala.meta.parsers.common.Parse
import scala.meta.parsers.common.ParseException
import scala.util.Try

case class DiffTest(spec: String, name: String, filename: String,
original: String, expected: String, skip: Boolean, only: Boolean,
style: ScalaStyle) {
val fullName = s"$spec: $name"
}

case class FormatOutput(token: String, whitespace: String, visits: Int)

case class Result(test: DiffTest, obtained: String, obtainedHtml: String,
tokens: Seq[FormatOutput], maxVisitsOnSingleToken: Int, visitedStates: Int,
timeNs: Long) {

def title = f"${test.name} (${timeMs}ms, $visitedStates states)"

def statesPerMs: Long = visitedStates / timeMs

def timeMs = TimeUnit.MILLISECONDS.convert(timeNs, TimeUnit.NANOSECONDS)
}

trait HasTests {
val testDir = "core/src/test/resources"

def isOnly(name: String) = name.startsWith("ONLY ")

def isSkip(name: String) = name.startsWith("SKIP ")

def stripPrefix(name: String) =
name.stripPrefix("SKIP ").stripPrefix("ONLY ").trim

def filename2parse(filename: String): Option[Parse[_ <: Tree]] =
extension(filename) match {
case "source" | "scala" => Some(scala.meta.parsers.parseSource)
case "stat" => Some(scala.meta.parsers.parseStat)
case "case" => Some(scala.meta.parsers.parseCase)
case _ => None
}

def extension(filename: String): String = filename.replaceAll(".*\\.", "")

def tests: Seq[DiffTest]
}

class FormatTest extends FunSuite with Timeouts with ScalaFmtLogger
with BeforeAndAfterAll with HasTests {
Expand Down Expand Up @@ -107,7 +68,7 @@ class FormatTest extends FunSuite with Timeouts with ScalaFmtLogger

def saveResult(t: DiffTest, obtained: String): Unit = {
val visitedStates = Debug.exploredInTest
logger.debug(f"$visitedStates%-4s ${t.fullName}")
// logger.debug(f"$visitedStates%-4s ${t.fullName}")
val output = getFormatOutput(t.style)
val obtainedHtml = Report.mkHtml(output, t.style)
debugResults += Result(t,
Expand Down