Repository navigation
Separate harness implementation from the harness framework - #446
rafaelfranca wants to merge 17 commits into
Conversation
Could you fix this warning? (I'm sorry if it wasn't new)
Do you know why the stackprof harness is loaded on the |
eccdfb4 to
d3153ab
Compare
c82ec54 to
82e0b03
Compare
82e0b03 to
01698a8
Compare
|
Given there is a My concern is I think we should not introduce "yet another way to run benchmarks". To be fair |
eregon
left a comment
There was a problem hiding this comment.
LGTM but I would just remove run_once.rb, it seems unnecessary and we already have 2 ways to run benchmarks (run_benchmarks.rb and directly with ruby ... benchmark.rb)
|
I can take a look at the test failures on truffleruby and push a commit to fix them if you'd like, let me know if so. |
4a80027 to
62c21c2
Compare
|
Ok. This PR has been approved and unmerged fora while now. I've taken it on and rebased it on top of the latest main and fixed a few things:
Few other documentation fixes and nits. Because of these changes I'm going to re-request review before merging. Thanks folks. |
Use file based harness instead of directory based harness
… selection So we don't need to deal with the `-r` ruby argument directly for selecting harnesses.
This allow `ruby` script direct calls to still select the harness without using any wrapper script.
lib/harness/extra.rb moved from harness/ to lib/harness/ but still built its output path from ../data, so the stackprof and vernier harnesses wrote to lib/data, which does not exist. harness_name also matched any */harness/*.rb feature, so lib/harness/loader.rb won and vernier named its profile loader-*.json. In this commit we build the output path from ../../data and take the harness name only from files directly inside the top level harness directory.
The loader passed HARNESS to require as a bare feature name. When a gem has the same name, such as stackprof or vernier, require loaded the gem and run_benchmark was never defined. In this commit we require harness/<name>.rb by its absolute path and keep the error that lists the available harnesses.
The default harness was selected by passing no -r at all, which left the choice to lib/harness/loader.rb. The loader reads HARNESS first, so an exported HARNESS replaced --harness=default and default_harness: default in benchmarks.yml, while the result was still labelled default. In this commit we set HARNESS to the resolved harness in the environment of the benchmark process. The harness that BenchmarkSuite picks is now the harness that the benchmark loads, whatever the parent environment holds.
The harness was passed as -r ahead of the --with-pre-init library, so Ruby loaded a non-default harness first. The Ractor harness calls Ractor.make_shareable(self) at load time, which froze main before the pre-init file ran, and a pre-init that set a top-level instance variable raised FrozenError. The default harness still loaded after pre-init, from the benchmark, so the order also depended on the harness. In this commit we pass the pre-init library before the harness. The pre-init file now runs before every harness, as it did when the benchmark itself loaded the harness.
Before the harnesses moved to harness/<name>.rb, --harness=harness selected the default harness. The prefix stripping turned harness-<name> into <name> but left harness unchanged, so every benchmark tried to load harness/harness.rb and failed with LoadError. The help text still named harness as the default. In this commit we map harness to default and change the help text to say default.
There are already two ways to run a benchmark: run_benchmarks.rb, and ruby on the benchmark file, where HARNESS or -r selects the harness and WARMUP_ITRS, MIN_BENCH_ITRS and MIN_BENCH_TIME set the iterations. run_once.rb added a third way that wrapped the second one in an exec. In this commit we remove run_once.rb and its tests. The CI job that ran it now runs railsbench once directly with ruby, and the README and lib/harness/loader.rb no longer refer to the script. The README example that runs a benchmark directly now sets WARMUP_ITRS=0 MIN_BENCH_ITRS=1 MIN_BENCH_TIME=0, the same values that run_benchmarks.rb --once sets.
burn_in.rb ran ruby -Iharness -r<name>. Now that harness/ holds stackprof.rb and vernier.rb, -Iharness let those files shadow the stackprof and vernier gems. railsbench calls Bundler.require, so it loaded harness/stackprof.rb instead of the gem and failed with uninitialized constant StackProf. In this commit we pass the harness to -r by absolute path and drop -Iharness, the same way lib/benchmark_suite.rb does. The harness directory never enters $LOAD_PATH, so gem requires resolve to gems.
The README said chained harnesses run in sequence and that once,default runs the benchmark once and then with default iterations. harness/chain.rb nests them instead: the first harness is the outermost, so once,default ran the default iterations inside a single once call and then once overwrote the results with a fake 1ms sample. The ractor example also pointed at benchmarks-ractor/, which does not exist. In this commit we describe the nesting, state that the outermost harness writes the results that are kept, and replace both examples with vernier,default and vernier,ractor on benchmarks/fib.rb.
The usage examples still passed -I harness-stackprof, a directory that no longer exists, and the second example set MIN_BENCH_ITRS=10 twice. HARNESS=stackprof already selects the harness, so the commands only worked because Ruby ignores a missing -I path.
The usage examples still passed -I harness-vernier, a directory that no longer exists, and the header named the variable NO_VIERWER although the harness reads NO_VIEWER. HARNESS=vernier already selects the harness.
62c21c2 to
47775f9
Compare
I had to spent some time understanding how the harness worked in this project. I realized that there were multiple directories for them and didn't know why.
I later realized that some were different harness implementation, and the harness folder was both the implementation and the framework.
I made this change the separate those two concepts, and remove the need to have different directories for implementation.
The framework lives in
lib/harnessand the implementations live inharness, in separated files (ractor.rb,perf.rb, etc.)