@@ -33,41 +33,53 @@ def initialize(categories:, name_filters:, excludes: [], out_path:, harness:, ha
3333 @bench_dir = BENCHMARKS_DIR
3434 end
3535
36- # Run all the benchmarks and record execution times
37- # Returns [bench_data, bench_failures]
38- def run ( ruby :, ruby_description :)
39- bench_data = { }
40- bench_failures = { }
36+ # Discovered and filtered benchmark entries, memoized.
37+ def benchmarks
38+ @benchmarks ||= discover_benchmarks
39+ end
4140
42- benchmark_entries = discover_benchmarks
41+ # Run a single benchmark entry on a single executable.
42+ # Returns { name:, data: } on success, { name:, failure: } on error.
43+ def run_benchmark ( entry , ruby :, ruby_description :)
4344 env = benchmark_env ( ruby )
4445 caller_json_path = ENV [ "RESULT_JSON_PATH" ]
45-
46- # Capture quiet setting before entering unbundled env (which clears ENV)
4746 quiet = ENV [ 'BENCHMARK_QUIET' ] == '1'
4847
49- benchmark_entries . each_with_index do | entry , idx |
50- puts ( "Running benchmark \" #{ entry . name } \" ( #{ idx + 1 } / #{ benchmark_entries . length } )" )
48+ result_json_path = caller_json_path || File . join ( out_path , "temp #{ Process . pid } .json" )
49+ cmd_prefix = base_cmd ( ruby_description , entry . name )
5150
52- result_json_path = caller_json_path || File . join ( out_path , "temp#{ Process . pid } .json" )
53- cmd_prefix = base_cmd ( ruby_description , entry . name )
54-
55- # Clear project-level Bundler environment so benchmarks run in a clean context.
56- # Benchmarks that need Bundler (e.g., railsbench) set up their own via use_gemfile.
57- # This is important when running tests under `bundle exec rake test`.
58- result = if defined? ( Bundler )
59- Bundler . with_unbundled_env do
60- run_single_benchmark ( entry . script_path , result_json_path , ruby , cmd_prefix , env , entry . name , quiet : quiet )
61- end
62- else
51+ # Clear project-level Bundler environment so benchmarks run in a clean context.
52+ # Benchmarks that need Bundler (e.g., railsbench) set up their own via use_gemfile.
53+ result = if defined? ( Bundler )
54+ Bundler . with_unbundled_env do
6355 run_single_benchmark ( entry . script_path , result_json_path , ruby , cmd_prefix , env , entry . name , quiet : quiet )
6456 end
57+ else
58+ run_single_benchmark ( entry . script_path , result_json_path , ruby , cmd_prefix , env , entry . name , quiet : quiet )
59+ end
60+
61+ if result [ :success ]
62+ { name : entry . name , data : process_benchmark_result ( result_json_path , result [ :command ] , delete_file : !caller_json_path ) }
63+ else
64+ FileUtils . rm_f ( result_json_path ) unless caller_json_path
65+ { name : entry . name , failure : result [ :status ] . exitstatus }
66+ end
67+ end
6568
66- if result [ :success ]
67- bench_data [ entry . name ] = process_benchmark_result ( result_json_path , result [ :command ] , delete_file : !caller_json_path )
69+ # Run all the benchmarks and record execution times.
70+ # Returns [bench_data, bench_failures]
71+ def run ( ruby :, ruby_description :)
72+ bench_data = { }
73+ bench_failures = { }
74+
75+ benchmarks . each_with_index do |entry , idx |
76+ puts ( "Running benchmark \" #{ entry . name } \" (#{ idx +1 } /#{ benchmarks . length } )" )
77+
78+ result = run_benchmark ( entry , ruby : ruby , ruby_description : ruby_description )
79+ if result [ :data ]
80+ bench_data [ entry . name ] = result [ :data ]
6881 else
69- bench_failures [ entry . name ] = result [ :status ] . exitstatus
70- FileUtils . rm_f ( result_json_path ) unless caller_json_path
82+ bench_failures [ entry . name ] = result [ :failure ]
7183 end
7284 end
7385
@@ -174,6 +186,11 @@ def benchmark_harness_for(benchmark_name)
174186 end
175187
176188 def benchmark_env ( ruby )
189+ @benchmark_env_cache ||= { }
190+ @benchmark_env_cache [ ruby ] ||= compute_benchmark_env ( ruby )
191+ end
192+
193+ def compute_benchmark_env ( ruby )
177194 # When the Ruby running this script is not the first Ruby in PATH, shell commands
178195 # like `bundle install` in a child process will not use the Ruby being benchmarked.
179196 # It overrides PATH to guarantee the commands of the benchmarked Ruby will be used.
0 commit comments