Skip to content

Conversation

luke-gruber
Copy link
Collaborator

@luke-gruber luke-gruber commented Aug 8, 2025

This PR introduces a set of benchmarks for assessing the performance of Ractors. The main parts of this work are

1. Introduce a set of Ractor specific performance benchmarks

A new harness harness-ractor.rb has been introduced. This harness will run the benchmark code inside a number of Ractors concurrently and collect timing information. By default this is 0 (ractors disabled), 1, 2, 4 and 8.

A number of Ractor specific benchmarks designed to test specific scenarios of multi-ractor mode have been introduced into the benchmarks-ractor directory. They've also been included in benchmarks.yml with the name prefix ractor/.

In order to run these benchmarks with the new harness a new category ractor-only has been introduced. The ractor only benchmarks can be run as follows:

./run_benchmarks.rb --category=ractor-only

2. Adapt existing benchmarks to be Ractor compatible

Existing benchmarks in the benchmarks directory have been updated (where it's possible to do so in a simple manner) to be multi-Ractor safe (mostly making sure any common state is made shareable using Ractor.make_shareable). Benchmarks that have been updated in this way have been marked inside benchmarks.yml with ractor: true.

These tests can be run with either the normal benchmark harness or the Ractor harness, they should be expected to work with both.

A new category ractor has been introduced that will run all of these tests with the Ractor harness alongside the Ractor only tests mentioned above.

All Ractor benchmarks can be run as follows:

./run_benchmarks.rb --category=ractor

Any benchmark can be run with the Ractor harness using the run_once.sh script in conjunction with the HARNESS environment variable

HARNESS=harness-ractor ./run_once.sh benchmarks/activerecord/benchmark.rb

Or a category can be run using the --harness argument to the main benchmark runner

./run_benchmarks.rb --harness=harness-ractor --category=headline

But be aware that running like this will ignore the ractor key in benchmarks.yml and will run all the chosen benchmarks with the ractor harness, regardless of compatibility. Crashes are likely.

3. Harness chain.

For convenience and as an aid to profiling with ractors, this PR also implements the ability to chain harnesses together. For example, running the ractor-only benchmarks through the Vernier profiler can be done as follows:

HARNESS_CHAIN="vernier,ractor" ./run_benchmarks.rb --harness=harness-chain --category=ractor-only

@luke-gruber luke-gruber marked this pull request as draft August 8, 2025 18:31
@luke-gruber luke-gruber force-pushed the ractor-harness-luke branch 2 times, most recently from 9a48fe5 to 607cd5b Compare August 12, 2025 15:39
eightbitraptor and others added 12 commits October 15, 2025 19:36
Co-Authored-By: Luke Gruber <[email protected]>
Co-Authored-By: Étienne Barrié <[email protected]>
Committed seperately so the noisy diff can be easily excluded from
reviews if needed.
These can be run as follows:

ruby -Iharness-ractor/harness.rb benchmarks-ractor/json_parse_float/benchmark.rb

Co-Authored-By: Luke Gruber <[email protected]>
If your ruby's bundler is different from the saved result in
`Gemfile.lock`, bundler autoswitches by starting a new process. When it
does this it sometimes doesn't pick up the old LOAD_PATH and results in
a LoadError.

Switch to use `Bundler.setup`, which is a simpler process and uses the
current bundler.
2 implementations, one using Process.fork, and one using Ractors - for
comparison
This is a copy of the Optcarrot benchmark from benchmarks/optcarrot, but
modified to be compatible with multiple Ractors
Instead -Iharness-name can be used
This commit introduces a harness that can be used to chain two (or more)
harnesses together.

For example. To run a Ractor test with Vernier you can wrap the ractor
harness with the vernier one as follows

HARNESS_CHAIN="vernier,ractor" ruby -Iharness-chain benchmarks-ractor/optcarrot/benchmark.rb
This commit modifies the benchmark runner to add 2 new categories:

--category=ractor-only Runs only those benchmarks in benchmarks-ractor
using the Ractor harness.

--category=ractor In addition to the ractor-only benchmarks, this will
run benchmarks specified in benchmarks.yml with `ractor: true` using the
Ractor harness.

In addition to this we've modified the burn in and run once scripts to
use the new harnesses and categories too

Co-Authored-By: Luke Gruber <[email protected]>
Also make sure that the benchmarks list test is up to date
@eightbitraptor eightbitraptor changed the title [WIP] Ractor harness Introduce Ractor benchmarks and harness Oct 15, 2025
@eightbitraptor eightbitraptor marked this pull request as ready for review October 15, 2025 19:18
@eightbitraptor eightbitraptor self-assigned this Oct 15, 2025
@tenderlove
Copy link
Member

This looks good to me, but I feel I'm missing something. Are the bechmarks just copied fully in to benchmarks-ractor and then made to be Ractor compatible? Also it seems like there were a bunch of images copied, should they have been?

@luke-gruber
Copy link
Collaborator Author

luke-gruber commented Oct 15, 2025

Some benchmark directories were copied into benchmarks-ractor, then made to work with ractors using the ractor harness. Others required just a few small changes so were not copied, but were made to work with the ractor harness. The ractor harness takes care of creating the ractors and running the run_benchmark block in parallel. I believe the images are all from copying optcarrot into benchmarks-ractor. We can remove them if you want.

@tenderlove
Copy link
Member

Some benchmark directories were copied into benchmarks-ractor, then made to work with ractors using the ractor harness. Others required just a few small changes so were not copied, but were made to work with the ractor harness. The ractor harness takes care of creating the ractors and running the run_benchmark block in parallel.

Got it, makes sense.

I believe the images are all from copying optcarrot into benchmarks-ractor. We can remove them if you want.

If they're not buying us anything, I think we should remove them. They look like possible benchmark results? I'd hate for people to be confused by them.

@eregon
Copy link
Member

eregon commented Oct 15, 2025

Regarding OptCarrot, have you seen https://github.com/mame/optcarrot/blob/master/bin/optcarrot-bench-parallel-on-ractor ?

That seems like a nice way to make OptCarrot Ractor-compatible without copying many files.
That specific file could be modified to not run the benchmark (e.g. if $0 != __FILE__) and required by benchmarks/optcarrot/benchmark.rb if using the Ractor harness (like for other benchmarks which were not copied). Or e.g. just copying the .freeze calls in that file.

I think it's best to avoid large copies in the repo, and benchmarks-ractor/optcarrot seems the only offender in this PR.

@k0kubun
Copy link
Member

k0kubun commented Oct 16, 2025

Looks good to me.

Make 30k_methods benchmark Ractor compatible

What was the change? The diff is so large that GitHub doesn't show the diff.

Regarding OptCarrot, have you seen https://github.com/mame/optcarrot/blob/master/bin/optcarrot-bench-parallel-on-ractor ?

If this is possible, I guess we could let benchmarks-ractor/optcarrot/benchmark.rb load optcarrot from ../../benchmarks/optcarrot, use shims like optcarrot-bench-parallel-on-ractor, and run the benchmark.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants