typelevel / typelevel/cats-effect
Create benchmarking infrastructure for JS (and Native?)
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 2.2k
- Forks
- 576
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 18
Description
(This issue is not directly about Cats Effect, but highly relevant to it.)
The lack of benchmarks for JS came up again recently wrt https://github.com/typelevel/cats-effect/pull/2673. Daniel and I had a discussion about this on Discord and I wanted to write some notes/braindump.
Firstly, although there is scalajs-benchmark, it is really designed for making interactive browser benchmarks which is very cool, but introduces various complications and sub-optimalities for our use-case. I kept a fork going for a while in https://github.com/typelevel/cats-effect/pull/2229 but it was a hack-job.
So, my (crazy) proposal to benchmark JS is to shim JMH, similarly to how Scala.js itself shims JUnit.
- Note that the JUnit shim had to add support for async tests, and we'd similarly have to make JMH support async benchmarks as well.
- Since all the existing benchmarks in CE end in
unsafeRunSync(), we can never achieve complete source-compatibility. It'll be annoying, but we can use aunsafeRunPlatform(...)method to share the benchmarks. - At first it seems like we need a mini-CE to implement this, but I actually don't think so. A benchmarking framework isn't some complicated concurrent program requiring fibers, cancellation etc. We can manage with
MacrotaskExecutorandFutureand if we can do without macrotask that would be even better because then we can use it to benchmark that too. - Although Scala.js doesn't directly support runtime annotations, it is possible to make them work. This is how JUnit.js works. IIUC it reads the annotations off of the corresponding
.classfiles and does something with them. - Hotspot and V8 are very different things, so some concepts may not translate well. We'll have to think about these.
So the overall goals would be:
- Source-compatibility with JMH, as much as possible. And similar output too for that matter.
- Minimal dependency, pure Scala.js. No fiddling with JavaScript dependencies.
- Ease-of-use directly from sbt. No fiddling with browser webpages.
- Compatible with all the "real" JSEnvs: Node.js and browsers.
- If it's not clear, this would be an independent project to CE of course :)
Why
- we can share the bulk of our existing benchmark suite with JVM/JS
- if it's easy enough to run, we'll do it more often, and learn how changes affect JS alongside JVM
- gives us the baseline to try experiments like a separate runloop for JS
- benchmark capabilities for JS can be interesting/helpful downstream in fs2, http4s, etc.
- oh, also maybe we'll make some meaningful optimizations :)
Why not
- major yak
- Performance can't be a first-class concern for both JVM and JS without splitting sources across platforms more frequently than we'd like. Since JVM rightfully takes priority, I'm not sure it's worth investing so much effort to create a benchmarking framework for JS.
- major yak
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the existing Cats Effect benchmarks and the scalajs-benchmark and JMH approaches described here, then examine how Scala.js handles async tests and runtime annotations. Define the independent project's sbt entry point and its support for Node.js and browsers. Done means a minimal pure-Scala.js benchmark framework with substantial JMH source and output compatibility.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, scala
- Domain
- performance, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100