Open
Description
Compiler version
3.6.3
Minimized example
xuwei-k/quote-pattern-match-benchmark@b2f2993
project/plugins.sbt
addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.7")
build.sbt
scalaVersion := "3.6.3"
enablePlugins(JmhPlugin)
libraryDependencies += "org.scala-lang" %% "scala3-tasty-inspector" % scalaVersion.value
Main.scala
package example
import scala.quoted._
import scala.tasty.inspector._
import org.openjdk.jmh.annotations.Benchmark
object Main {
val compilerJarPath: String =
dotty.tools.dotc.Main.getClass.getProtectionDomain.getCodeSource.getLocation.toURI.toURL.getFile
}
class Main {
inline def expected: Int = 125
@Benchmark
def lowLevelReflection(): Int = {
var count: Int = 0
val inspector: Inspector = new Inspector {
override def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit = {
import quotes.reflect.*
val traverser = new quotes.reflect.TreeTraverser {
override def traverseTree(tree: Tree)(owner: Symbol): Unit = {
if (tree.isExpr) {
tree match {
case Select(obj, "get") if obj.tpe <:< TypeRepr.of[Option[?]] =>
count += 1
case _ =>
super.traverseTree(tree)(owner)
}
} else {
super.traverseTree(tree)(owner)
}
}
}
tastys.foreach { t =>
traverser.traverseTree(t.ast)(Symbol.spliceOwner)
}
}
}
TastyInspector.inspectTastyFilesInJar(Main.compilerJarPath)(inspector)
assert(count == expected)
count
}
@Benchmark
def quoteMatch(): Int = {
var count: Int = 0
val inspector: Inspector = new Inspector {
override def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit = {
import quotes.reflect.*
val traverser = new quotes.reflect.TreeTraverser {
override def traverseTree(tree: Tree)(owner: Symbol): Unit = {
if (tree.isExpr) {
tree.asExpr match {
case '{ ($x: Option[t]).get } =>
count += 1
case _ =>
super.traverseTree(tree)(owner)
}
} else {
super.traverseTree(tree)(owner)
}
}
}
tastys.foreach { t =>
traverser.traverseTree(t.ast)(Symbol.spliceOwner)
}
}
}
TastyInspector.inspectTastyFilesInJar(Main.compilerJarPath)(inspector)
assert(count == expected)
count
}
}
run sbt "Jmh/run -i 10 -f1 -t1"
Output
[info] Benchmark Mode Cnt Score Error Units
[info] Main.lowLevelReflection thrpt 10 0.346 ± 0.006 ops/s
[info] Main.quoteMatch thrpt 10 0.052 ± 0.002 ops/s
0.346 / 0.052 = 6.65
Note
wartremover use many quote pattern matching. but I realized too slow quote pattern matching. I have added workaround