From 0e1ee81686b4f38b693a6fe1b30b51774d13fa0e Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Fri, 21 Nov 2025 20:09:59 +0100 Subject: [PATCH 1/3] Fix make_shareable shim in harness-common.rb * Ractor is not defined on non-CRuby. --- harness/harness-common.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/harness/harness-common.rb b/harness/harness-common.rb index 6c77a379..2329424c 100644 --- a/harness/harness-common.rb +++ b/harness/harness-common.rb @@ -13,10 +13,10 @@ # Seed the global random number generator for repeatability between runs Random.srand(1337) -if !Ractor.respond_to?(:make_shareable) +if !defined?(Ractor.make_shareable) class Ractor #noop - def make_shareable(obj, copy: false); obj; end + def self.make_shareable(obj, copy: false); obj; end end end From bb925571d229b6ffd24274a69f4be23d329d611d Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Fri, 21 Nov 2025 20:50:29 +0100 Subject: [PATCH 2/3] Define top-level #make_shareable to avoid defining Ractor * Defining Ractor causes issues with gems assuming the rest of Ractor is available, like: lib/mri/psych.rb:709:in `config': undefined method `current' for class Ractor (NoMethodError) --- benchmarks-ractor/json_parse_float/benchmark.rb | 2 +- benchmarks-ractor/json_parse_string/benchmark.rb | 2 +- benchmarks-ractor/knucleotide/benchmark.rb | 2 +- benchmarks/attr_accessor.rb | 2 +- benchmarks/blurhash/benchmark.rb | 2 +- benchmarks/erubi/benchmark.rb | 2 +- benchmarks/graphql/benchmark.rb | 8 ++++---- benchmarks/hexapdf/benchmark.rb | 4 ++-- benchmarks/lee/benchmark.rb | 8 ++++---- benchmarks/nbody/benchmark.rb | 2 +- benchmarks/optcarrot/benchmark.rb | 2 +- benchmarks/protoboeuf-encode/benchmark.rb | 2 +- benchmarks/protoboeuf/benchmark.rb | 2 +- benchmarks/psych-load/benchmark.rb | 2 +- benchmarks/railsbench/vendor/.keep | 0 benchmarks/ruby-json/benchmark.rb | 2 +- benchmarks/ruby-lsp/benchmark.rb | 4 ++-- benchmarks/rubyboy/benchmark.rb | 4 ++-- benchmarks/sudoku.rb | 6 +++--- harness/harness-common.rb | 11 +++++++---- 20 files changed, 36 insertions(+), 33 deletions(-) delete mode 100644 benchmarks/railsbench/vendor/.keep diff --git a/benchmarks-ractor/json_parse_float/benchmark.rb b/benchmarks-ractor/json_parse_float/benchmark.rb index 047cefd7..ef81bc49 100644 --- a/benchmarks-ractor/json_parse_float/benchmark.rb +++ b/benchmarks-ractor/json_parse_float/benchmark.rb @@ -12,7 +12,7 @@ rand, rand, rand, rand, rand, rand, rand, rand, rand, rand, ].to_json end -Ractor.make_shareable(list) +make_shareable(list) # Work is divided between ractors run_benchmark(5, ractor_args: [list]) do |num_rs, list| diff --git a/benchmarks-ractor/json_parse_string/benchmark.rb b/benchmarks-ractor/json_parse_string/benchmark.rb index 63664394..a579f805 100644 --- a/benchmarks-ractor/json_parse_string/benchmark.rb +++ b/benchmarks-ractor/json_parse_string/benchmark.rb @@ -30,7 +30,7 @@ "string #{i}" => "value #{i}", }.to_json end -Ractor.make_shareable(list) +make_shareable(list) # Work is divided between ractors run_benchmark(5, ractor_args: [list]) do |num_rs, list| diff --git a/benchmarks-ractor/knucleotide/benchmark.rb b/benchmarks-ractor/knucleotide/benchmark.rb index 85236573..ca5b9cd9 100644 --- a/benchmarks-ractor/knucleotide/benchmark.rb +++ b/benchmarks-ractor/knucleotide/benchmark.rb @@ -52,7 +52,7 @@ def generate_test_sequence(size) end # Make sequence shareable for Ractors -TEST_SEQUENCE = Ractor.make_shareable(generate_test_sequence(100_000)) +TEST_SEQUENCE = make_shareable(generate_test_sequence(100_000)) run_benchmark(5) do |num_ractors, ractor_args| freqs = [1, 2] diff --git a/benchmarks/attr_accessor.rb b/benchmarks/attr_accessor.rb index 5ad0d521..d5e397dc 100644 --- a/benchmarks/attr_accessor.rb +++ b/benchmarks/attr_accessor.rb @@ -35,7 +35,7 @@ def get_value_loop end OBJ = TheClass.new -Ractor.make_shareable(OBJ) +make_shareable(OBJ) run_benchmark(10) do OBJ.get_value_loop diff --git a/benchmarks/blurhash/benchmark.rb b/benchmarks/blurhash/benchmark.rb index 112f2897..1f081f4b 100644 --- a/benchmarks/blurhash/benchmark.rb +++ b/benchmarks/blurhash/benchmark.rb @@ -176,7 +176,7 @@ def blurHashForPixels(xComponents, yComponents, width, height, rgb, bytesPerRow) FILE = File.join(__dir__, "test.bin") -Ractor.make_shareable(ARRAY = File.read(FILE).bytes) +make_shareable(ARRAY = File.read(FILE).bytes) run_benchmark(10) do Blurhash.encode_rb(204, 204, ARRAY) diff --git a/benchmarks/erubi/benchmark.rb b/benchmarks/erubi/benchmark.rb index 1000352a..0a75f1bb 100644 --- a/benchmarks/erubi/benchmark.rb +++ b/benchmarks/erubi/benchmark.rb @@ -58,7 +58,7 @@ def run_erb # This is taken from actual "gem server" data VALUES = JSON.load(File.read "gem_specs.json") -Ractor.make_shareable(VALUES) +make_shareable(VALUES) check_result_size(ErbRenderer.new(VALUES).run_erb) run_benchmark(50) do diff --git a/benchmarks/graphql/benchmark.rb b/benchmarks/graphql/benchmark.rb index 8b6d1ecf..85b5da1f 100644 --- a/benchmarks/graphql/benchmark.rb +++ b/benchmarks/graphql/benchmark.rb @@ -5,16 +5,16 @@ require "graphql" -DATA = Ractor.make_shareable(File.read "negotiate.gql") +DATA = make_shareable(File.read "negotiate.gql") if ENV["RUBY_BENCH_RACTOR_HARNESS"] GraphQL.default_parser - Ractor.make_shareable(GraphQL::Tracing::NullTrace) + make_shareable(GraphQL::Tracing::NullTrace) GraphQL::Language::Lexer.constants.each do |constant| - Ractor.make_shareable(GraphQL::Language::Lexer.const_get(constant)) + make_shareable(GraphQL::Language::Lexer.const_get(constant)) end GraphQL::Language::Parser.constants.each do |constant| - Ractor.make_shareable(GraphQL::Language::Parser.const_get(constant)) + make_shareable(GraphQL::Language::Parser.const_get(constant)) end end diff --git a/benchmarks/hexapdf/benchmark.rb b/benchmarks/hexapdf/benchmark.rb index 564efa4d..9609139b 100644 --- a/benchmarks/hexapdf/benchmark.rb +++ b/benchmarks/hexapdf/benchmark.rb @@ -19,8 +19,8 @@ Dir["/tmp/hexapdf-result*.pdf"].each { |file| FileUtils.rm file } if ENV["RUBY_BENCH_RACTOR_HARNESS"] - Ractor.make_shareable(HexaPDF::DefaultDocumentConfiguration) - Ractor.make_shareable(HexaPDF::GlobalConfiguration) + make_shareable(HexaPDF::DefaultDocumentConfiguration) + make_shareable(HexaPDF::GlobalConfiguration) # TODO... still doesn't work end diff --git a/benchmarks/lee/benchmark.rb b/benchmarks/lee/benchmark.rb index 415301e1..2abdd945 100644 --- a/benchmarks/lee/benchmark.rb +++ b/benchmarks/lee/benchmark.rb @@ -87,10 +87,10 @@ def lay(depth, solution) Dir.chdir __dir__ use_gemfile -BOARD = Ractor.make_shareable(board) -OBSTRUCTED = Ractor.make_shareable(obstructed) -OUTPUT_FILENAME = Ractor.make_shareable(output_filename) -EXPANSIONS_DIR = Ractor.make_shareable(expansions_dir) +BOARD = make_shareable(board) +OBSTRUCTED = make_shareable(obstructed) +OUTPUT_FILENAME = make_shareable(output_filename) +EXPANSIONS_DIR = make_shareable(expansions_dir) run_benchmark(10) do depth = Lee::Matrix.new(BOARD.height, BOARD.width) diff --git a/benchmarks/nbody/benchmark.rb b/benchmarks/nbody/benchmark.rb index fb3be0fd..737e298b 100644 --- a/benchmarks/nbody/benchmark.rb +++ b/benchmarks/nbody/benchmark.rb @@ -134,7 +134,7 @@ def offset_momentum(bodies) N = 20000 NBODIES = BODIES.size if ENV["RUBY_BENCH_RACTOR_HARNESS"] - Ractor.make_shareable(BODIES) + make_shareable(BODIES) end DT = 0.01 diff --git a/benchmarks/optcarrot/benchmark.rb b/benchmarks/optcarrot/benchmark.rb index 810f9d71..3c48515f 100755 --- a/benchmarks/optcarrot/benchmark.rb +++ b/benchmarks/optcarrot/benchmark.rb @@ -24,7 +24,7 @@ Optcarrot::PPU::NMT_TABLE, Optcarrot::CPU::DISPATCH, Optcarrot::ROM::MAPPER_DB, - ].each { |const| Ractor.make_shareable(const) } + ].each { |const| make_shareable(const) } ROM_PATH = File.join(__dir__, "examples/Lan_Master.nes").freeze ENV["WARMUP_ITRS"] = "1" diff --git a/benchmarks/protoboeuf-encode/benchmark.rb b/benchmarks/protoboeuf-encode/benchmark.rb index 7a2c3f27..a7afcdb7 100644 --- a/benchmarks/protoboeuf-encode/benchmark.rb +++ b/benchmarks/protoboeuf-encode/benchmark.rb @@ -5,7 +5,7 @@ Dir.chdir __dir__ fake_msg_bins = Marshal.load(File.binread('encoded_msgs.bin')) -LOTS = Ractor.make_shareable(fake_msg_bins.map { |bin| ProtoBoeuf::ParkingLot.decode bin }) +LOTS = make_shareable(fake_msg_bins.map { |bin| ProtoBoeuf::ParkingLot.decode bin }) run_benchmark(20) do LOTS.each { |lot| ProtoBoeuf::ParkingLot.encode lot } diff --git a/benchmarks/protoboeuf/benchmark.rb b/benchmarks/protoboeuf/benchmark.rb index 4938d2ab..6e3078f4 100644 --- a/benchmarks/protoboeuf/benchmark.rb +++ b/benchmarks/protoboeuf/benchmark.rb @@ -4,7 +4,7 @@ require_relative 'benchmark_pb' Dir.chdir __dir__ -FAKE_MSG_BINS = Ractor.make_shareable(Marshal.load(File.binread('encoded_msgs.bin'))) +FAKE_MSG_BINS = make_shareable(Marshal.load(File.binread('encoded_msgs.bin'))) run_benchmark(20) do FAKE_MSG_BINS.each { |bin| ProtoBoeuf::ParkingLot.decode bin } diff --git a/benchmarks/psych-load/benchmark.rb b/benchmarks/psych-load/benchmark.rb index ad49f8cc..795135f3 100644 --- a/benchmarks/psych-load/benchmark.rb +++ b/benchmarks/psych-load/benchmark.rb @@ -16,7 +16,7 @@ raise "Not loading any YAML files!" end -TEST_YAML = Ractor.make_shareable(test_yaml_files.map { |p| File.read(p) }) +TEST_YAML = make_shareable(test_yaml_files.map { |p| File.read(p) }) run_benchmark(10) do test_yaml = TEST_YAML diff --git a/benchmarks/railsbench/vendor/.keep b/benchmarks/railsbench/vendor/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/benchmarks/ruby-json/benchmark.rb b/benchmarks/ruby-json/benchmark.rb index 4aa0d2c9..3c2d3e4e 100644 --- a/benchmarks/ruby-json/benchmark.rb +++ b/benchmarks/ruby-json/benchmark.rb @@ -141,6 +141,6 @@ def parse_item # Public domain football data taken from: # https://github.com/openfootball/football.json/blob/master/2011-12/at.1.json -SOURCE = Ractor.make_shareable(IO.read("#{__dir__}/data.json")) +SOURCE = make_shareable(IO.read("#{__dir__}/data.json")) run_benchmark(10) { source = SOURCE; 100.times { JSONParser.new(source).parse } } diff --git a/benchmarks/ruby-lsp/benchmark.rb b/benchmarks/ruby-lsp/benchmark.rb index 513ebb3d..232a0e8d 100644 --- a/benchmarks/ruby-lsp/benchmark.rb +++ b/benchmarks/ruby-lsp/benchmark.rb @@ -11,8 +11,8 @@ require "ruby_lsp/internal" path = File.expand_path("fixture.rb", __dir__) -INDEX_PATH = Ractor.make_shareable(RubyIndexer::IndexablePath.new(File.expand_path("../..", __dir__), path)) -CONTENT = Ractor.make_shareable(File.read(path)) +INDEX_PATH = make_shareable(RubyIndexer::IndexablePath.new(File.expand_path("../..", __dir__), path)) +CONTENT = make_shareable(File.read(path)) run_benchmark(200) do RubyIndexer::Index.new.index_single(INDEX_PATH, CONTENT) diff --git a/benchmarks/rubyboy/benchmark.rb b/benchmarks/rubyboy/benchmark.rb index 9db59677..54b0d5e1 100644 --- a/benchmarks/rubyboy/benchmark.rb +++ b/benchmarks/rubyboy/benchmark.rb @@ -18,8 +18,8 @@ # needing to re-initialize but not sure how to determine that. COUNT = 500 -Ractor.make_shareable(Rubyboy::ApuChannels::Channel1::WAVE_DUTY) -Ractor.make_shareable(Rubyboy::ApuChannels::Channel2::WAVE_DUTY) +make_shareable(Rubyboy::ApuChannels::Channel1::WAVE_DUTY) +make_shareable(Rubyboy::ApuChannels::Channel2::WAVE_DUTY) run_benchmark(200) do # Results are much more consistent if we re-initialize each time. diff --git a/benchmarks/sudoku.rb b/benchmarks/sudoku.rb index a93db43e..62308b36 100644 --- a/benchmarks/sudoku.rb +++ b/benchmarks/sudoku.rb @@ -188,7 +188,7 @@ def sd_solve(mr, mc, s) end end -HARD20 = Ractor.make_shareable([ +HARD20 = make_shareable([ "..............3.85..1.2.......5.7.....4...1...9.......5......73..2.1........4...9", ".......12........3..23..4....18....5.6..7.8.......9.....85.....9...4.5..47...6...", ".2..5.7..4..1....68....3...2....8..3.4..2.5.....6...1...2.9.....9......57.4...9..", @@ -212,8 +212,8 @@ def sd_solve(mr, mc, s) ]) MR, MC = sd_genmat -Ractor.make_shareable(MR) -Ractor.make_shareable(MC) +make_shareable(MR) +make_shareable(MC) run_benchmark(20) do mr = MR diff --git a/harness/harness-common.rb b/harness/harness-common.rb index 2329424c..eb2c3410 100644 --- a/harness/harness-common.rb +++ b/harness/harness-common.rb @@ -13,10 +13,13 @@ # Seed the global random number generator for repeatability between runs Random.srand(1337) -if !defined?(Ractor.make_shareable) - class Ractor - #noop - def self.make_shareable(obj, copy: false); obj; end +if defined?(Ractor.make_shareable) + def make_shareable(obj, copy: false) + Ractor.make_shareable(obj, copy: copy) + end +else + def make_shareable(obj, copy: false) + obj # noop end end From 704f891edab9bafe8f9f44a41d71728333d2abfe Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Fri, 21 Nov 2025 21:02:18 +0100 Subject: [PATCH 3/3] Don't run ractor-related CI jobs on truffleruby, they just fail --- .github/workflows/test.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e207e617..992abfee 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,7 +51,7 @@ jobs: strategy: fail-fast: false matrix: - ruby: [ruby, head, truffleruby] + ruby: [ruby, head] if: ${{ github.event_name != 'schedule' || github.repository == 'ruby/ruby-bench' }} steps: - uses: actions/checkout@v3 @@ -66,14 +66,13 @@ jobs: WARMUP_ITRS: '1' MIN_BENCH_ITRS: '1' MIN_BENCH_TIME: '0' - continue-on-error: ${{ matrix.ruby == 'truffleruby' }} benchmark-ractor-only: runs-on: ubuntu-latest strategy: fail-fast: false matrix: - ruby: [ruby, head, truffleruby] + ruby: [ruby, head] if: ${{ github.event_name != 'schedule' || github.repository == 'ruby/ruby-bench' }} steps: - uses: actions/checkout@v3 @@ -88,7 +87,6 @@ jobs: WARMUP_ITRS: '1' MIN_BENCH_ITRS: '1' MIN_BENCH_TIME: '0' - continue-on-error: ${{ matrix.ruby == 'truffleruby' }} benchmark-graph: runs-on: ubuntu-latest