|
| 1 | +package sjsonnet.bench |
| 2 | + |
| 3 | +import org.openjdk.jmh.annotations.* |
| 4 | +import org.openjdk.jmh.infra.* |
| 5 | +import sjsonnet.* |
| 6 | + |
| 7 | +import java.io.{ByteArrayOutputStream, OutputStream, PrintStream, StringWriter} |
| 8 | +import java.util.concurrent.TimeUnit |
| 9 | + |
| 10 | +/** |
| 11 | + * A/B benchmark comparing old (instanceof chain) vs new (tag + tableswitch) evaluator. |
| 12 | + * |
| 13 | + * Runs the full interpret pipeline (parse → optimize → evaluate → materialize) for each benchmark |
| 14 | + * file, isolating the evaluator difference by using the same Settings with only `useNewEvaluator` |
| 15 | + * toggled. |
| 16 | + */ |
| 17 | +@BenchmarkMode(Array(Mode.AverageTime)) |
| 18 | +@Fork(2) |
| 19 | +@Threads(1) |
| 20 | +@Warmup(iterations = 15) |
| 21 | +@Measurement(iterations = 20) |
| 22 | +@OutputTimeUnit(TimeUnit.MILLISECONDS) |
| 23 | +@State(Scope.Benchmark) |
| 24 | +class EvaluatorBenchmark { |
| 25 | + |
| 26 | + @Param( |
| 27 | + Array( |
| 28 | + // cpp_suite — C++ jsonnet benchmarks |
| 29 | + "bench/resources/cpp_suite/bench.01.jsonnet", |
| 30 | + "bench/resources/cpp_suite/bench.02.jsonnet", |
| 31 | + "bench/resources/cpp_suite/bench.03.jsonnet", |
| 32 | + "bench/resources/cpp_suite/bench.04.jsonnet", |
| 33 | + "bench/resources/cpp_suite/bench.06.jsonnet", |
| 34 | + "bench/resources/cpp_suite/bench.08.jsonnet", |
| 35 | + "bench/resources/cpp_suite/bench.09.jsonnet", |
| 36 | + "bench/resources/cpp_suite/gen_big_object.jsonnet", |
| 37 | + "bench/resources/cpp_suite/heavy_string_render.jsonnet", |
| 38 | + "bench/resources/cpp_suite/large_string_join.jsonnet", |
| 39 | + "bench/resources/cpp_suite/realistic1.jsonnet", |
| 40 | + "bench/resources/cpp_suite/realistic2.jsonnet", |
| 41 | + "bench/resources/cpp_suite/string_render_perf.jsonnet", |
| 42 | + // go_suite — Go jsonnet builtins |
| 43 | + "bench/resources/go_suite/base64_heavy.jsonnet", |
| 44 | + "bench/resources/go_suite/base64_mega.jsonnet", |
| 45 | + "bench/resources/go_suite/comparison.jsonnet", |
| 46 | + "bench/resources/go_suite/comparison2.jsonnet", |
| 47 | + "bench/resources/go_suite/foldl.jsonnet", |
| 48 | + "bench/resources/go_suite/reverse.jsonnet", |
| 49 | + "bench/resources/go_suite/substr.jsonnet", |
| 50 | + // bug_suite |
| 51 | + "bench/resources/bug_suite/assertions.jsonnet", |
| 52 | + // sjsonnet_suite |
| 53 | + "bench/resources/sjsonnet_suite/setDiff.jsonnet" |
| 54 | + ) |
| 55 | + ) |
| 56 | + var path: String = _ |
| 57 | + |
| 58 | + private var wd: os.Path = _ |
| 59 | + private var filePath: OsPath = _ |
| 60 | + private var fileContent: String = _ |
| 61 | + private var jpaths: Seq[OsPath] = _ |
| 62 | + |
| 63 | + @Setup(Level.Trial) |
| 64 | + def setup(): Unit = { |
| 65 | + wd = sys.env.get("MILL_WORKSPACE_ROOT").map(os.Path(_)).getOrElse(os.pwd) |
| 66 | + filePath = OsPath(wd / os.RelPath(path)) |
| 67 | + fileContent = os.read(wd / os.RelPath(path)) |
| 68 | + jpaths = Seq(OsPath(wd)) |
| 69 | + } |
| 70 | + |
| 71 | + private def run(useNew: Boolean): String = { |
| 72 | + val settings = new Settings( |
| 73 | + useNewEvaluator = useNew, |
| 74 | + maxStack = 100000 |
| 75 | + ) |
| 76 | + val interp = new Interpreter( |
| 77 | + Map.empty[String, String], |
| 78 | + Map.empty[String, String], |
| 79 | + OsPath(wd), |
| 80 | + importer = new SjsonnetMainBase.SimpleImporter(jpaths, None), |
| 81 | + parseCache = new DefaultParseCache, |
| 82 | + settings = settings |
| 83 | + ) |
| 84 | + val writer = new StringWriter |
| 85 | + val renderer = new Renderer(writer, indent = 3) |
| 86 | + interp.interpret0(fileContent, filePath, renderer) match { |
| 87 | + case Right(_) => writer.toString |
| 88 | + case Left(e) => throw new RuntimeException(e) |
| 89 | + } |
| 90 | + } |
| 91 | + |
| 92 | + @Benchmark |
| 93 | + def oldEvaluator(bh: Blackhole): Unit = { |
| 94 | + bh.consume(run(useNew = false)) |
| 95 | + } |
| 96 | + |
| 97 | + @Benchmark |
| 98 | + def newEvaluator(bh: Blackhole): Unit = { |
| 99 | + bh.consume(run(useNew = true)) |
| 100 | + } |
| 101 | +} |
0 commit comments