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

Address community feedback #27

Merged
merged 21 commits into from
Nov 25, 2017
Merged

Conversation

xeno-by
Copy link
Contributor

@xeno-by xeno-by commented Nov 24, 2017

This pull request adds a performance comparison between Rsc schedule and Scalac namer to sbt bench (#25) and also refactors the benchmark suite to support both Scala 2.11 and Scala 2.12 (#26).

Todo:

  • Update docs/compiler.md with a new section that provides a detailed description of similarities and differences between Rsc and Scalac pipelines.
  • Link the disclaimer in docs/performance.md to the aforementioned new section in documentation.
  • Update docs/performance.md with new performance numbers once our benchmark box finishes running the updated benchmarks.

/cc @dragos @adriaanm @retronym

@xeno-by xeno-by added this to the 0.1.0 "Bare minimum" milestone Nov 24, 2017
@CLAassistant
Copy link

CLAassistant commented Nov 24, 2017

CLA assistant check
All committers have signed the CLA.

build.sbt Outdated
)

lazy val benchScalac212 = project
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eed3si9n @dwijnand Can you provide some advice on deduplicating code in benchScalac211 and benchScalac212? Files in these two projects are currently completely identical, which is clearly suboptimal, but I don't know how to make sbt do my bidding otherwise.

My goal is to be able to say benchScalac211/jmh:run ... or benchScalac212/jmh:run ... and then have sbt run the same benchmarks for either Scala 2.11 or Scala 2.12.

Here's what I tried so far:

  • One project in conjunction with ++. This works, but I don't like the fact that users will have to know exact Scala versions (e.g. 2.12.4 vs simply 2.12) to run benchmarks. Even worse, if the user forgets to say ++, they may inadvertently run benchmarks for an unexpected version Scala. I think this is a big deal, because benchmarking is monotonous enough to make humans accidentally miss things like that.
  • Two projects that are rooted at the same directory. This seems to be illegal.
  • Three projects (a common project that crosscompiles to Scala 2.11 and Scala 2.12, as well as two projects that depend on it). This leads to an error similar to the one described at https://stackoverflow.com/questions/27929272/how-to-have-sbt-subproject-with-multiple-scala-versions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s a bit hacky but I think you can use separate empty project directories and set them to have the same managed sources (or additional sources) to get around the fact that two projects can’t have the same directory.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting idea, thanks! Let's keep this in mind for the future.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, with all the reasonable-scala repo activity I missed this notification was directly at me.

I too would go the way of adding a shared source directory to both projects.

def run(bs: BenchmarkState): Unit = {
runImpl(bs)
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@retronym I've been meaning to compare notes wrt. scala/compiler-benchmark right after we opensourced Rsc, but forgot about that in the post-release rush. Looks like we have another good opportunity to chat.

Just like you guys, we found it useful to split benchmarks into cold, warm and hot. In our benchmarks, cold and hot cover two important use cases - single-shot CLI runs and resident compilations. Moreover, we use warm to get a quick & dirty approximation of hot during interactive development.

Unfortunately, because of the peculiar configuration style of JMH, we haven't found a way to abstract these notions, so we have to create endless bunches of ColdXxxYyy, WarmXxxYyy and HotXxxYyy classes with the same JMH annotations repeated over and over again.

I guess you guys faced the same problem in scala/compiler-benchmark. Do you maybe have some ideas how to cut down on duplication?

build.sbt Outdated
.enablePlugins(JmhPlugin)
.jvmSettings(benchCliRscNative("Typecheck"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can resolve #22 in the pr while you're at it by adding:

.nativeSettings(nativeMode := "release)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit splits project `bench` into multiple projects:
`benchJavac18`, `benchRsc`, `benchScalac211` and `benchScalac212`.
This provides additional flexibility and fine-grained control over
target compiler versions.

The main motivation for this change is the fact that neither Scala 2.11
nor Scala 2.12 clearly dominate one another on re2s. Scala 2.11 is
faster in cold mode, whereas Scala 2.12 is faster in hot mode.

While refactoring the benchmarking infrastructure to accommodate this
change, I've also retired CliBench. It is confusing to have multiple
benchmarks that test the same thing (ColdXxxYyy and CliXxxYyy),
so I picked the one that's simpler, i.e. ColdXxxYyy powered by JMH.
RscNativeTypecheck is still powered by CliBench-like logic, but it has
been merged directly into that particular benchmark.

I am not completely happy with the astonishing degree of duplication
between benchScalac211 and benchScalac212, but my sbt skills don't
allow me to remove this duplication in a satisfying manner. (I'm aware
of ++, but I want Scala versions to be part of the project name, not
an optional prefix to an sbt invocation.)
This will make it easier to interpret benchmark results - both via
eyeballing and via automated processing.
> benchRscJVM/benchRscNativeSchedule
[info] Linking (1053 ms)
[info] Discovered 2088 classes and 15212 methods
[info] Optimizing (1377 ms)
[info] Generating intermediate code (418 ms)
[info] Produced 54 files
[info] Compiling to native code (1266 ms)
[info] Linking native code (205 ms)
[info] Running rsc.bench.RscNativeSchedule ~/Projects/rsc/bench/rsc/native/target/scala-2.11/benchrscnative-out
...

Result "rsc.bench.ColdRscNativeSchedule.run":
  N = 100
  mean = 146.522 ms/op

Benchmark                  Mode  Cnt    Score  Units
ColdRscNativeSchedule.run   cli  100  146.522  ms/op

...

Result "rsc.bench.HotRscNativeSchedule.run":
  N = 1
  mean = 119.297 ms/op

Benchmark                 Mode  Cnt    Score  Units
HotRscNativeSchedule.run   cli    1  119.297  ms/op
[success] Total time: 32 s, completed Nov 24, 2017 2:23:06 PM
Concretely:
  * ScalacScanNnn => ScalacScannerNnn
  * ScalacParseNnn => ScalacParserNnn
  * ScalacNameNnn => ScalacNamerNnn
  * ScalacTypecheckNnn => ScalacTyperNnn

These names break consistency with the corresponding Rsc benchmarks,
but make it easy to correlate what's going on with the corresponding
Scalac modules.
ShaneDelmore
ShaneDelmore previously approved these changes Nov 25, 2017
Copy link
Contributor

@ShaneDelmore ShaneDelmore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice PR. I especially appreciated the script to update performance.md.

@ShaneDelmore ShaneDelmore merged commit 85f54b1 into twitter:master Nov 25, 2017
@xeno-by xeno-by deleted the community-feedback branch November 25, 2017 18:34
@xeno-by xeno-by added the Docs label Jul 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

4 participants