diff options
| author | Jean Boussier <jean.boussier@gmail.com> | 2025-08-06 14:46:36 +0200 |
|---|---|---|
| committer | Jean Boussier <jean.boussier@gmail.com> | 2025-08-06 17:07:49 +0200 |
| commit | f3206cc79bec2fd852e81ec56de59f0a67ab32b7 (patch) | |
| tree | 31fc6f687c839558a071445c0a90fd6cbf3c0ad1 /test/ruby/test_ractor.rb | |
| parent | 9b3ad3449be62c46fbacdb59f43aa526f7da2f79 (diff) | |
Struct: keep direct reference to IMEMO/fields when space allows
It's not rare for structs to have additional ivars, hence are one
of the most common, if not the most common type in the `gen_fields_tbl`.
This can cause Ractor contention, but even in single ractor mode
means having to do a hash lookup to access the ivars, and increase
GC work.
Instead, unless the struct is perfectly right sized, we can store
a reference to the associated IMEMO/fields object right after the
last struct member.
```
compare-ruby: ruby 3.5.0dev (2025-08-06T12:50:36Z struct-ivar-fields-2 9a30d141a1) +PRISM [arm64-darwin24]
built-ruby: ruby 3.5.0dev (2025-08-06T12:57:59Z struct-ivar-fields-2 2ff3ec237f) +PRISM [arm64-darwin24]
warming up.....
| |compare-ruby|built-ruby|
|:---------------------|-----------:|---------:|
|member_reader | 590.317k| 579.246k|
| | 1.02x| -|
|member_writer | 543.963k| 527.104k|
| | 1.03x| -|
|member_reader_method | 213.540k| 213.004k|
| | 1.00x| -|
|member_writer_method | 192.657k| 191.491k|
| | 1.01x| -|
|ivar_reader | 403.993k| 569.915k|
| | -| 1.41x|
```
Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com>
Diffstat (limited to 'test/ruby/test_ractor.rb')
| -rw-r--r-- | test/ruby/test_ractor.rb | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/test/ruby/test_ractor.rb b/test/ruby/test_ractor.rb index 97af7e7413..0a456a1d0f 100644 --- a/test/ruby/test_ractor.rb +++ b/test/ruby/test_ractor.rb @@ -99,6 +99,24 @@ class TestRactor < Test::Unit::TestCase RUBY end + def test_struct_instance_variables + assert_ractor(<<~'RUBY') + StructIvar = Struct.new(:member) do + def initialize(*) + super + @ivar = "ivar" + end + attr_reader :ivar + end + obj = StructIvar.new("member") + obj_copy = Ractor.new { Ractor.receive }.send(obj).value + assert_equal obj.ivar, obj_copy.ivar + refute_same obj.ivar, obj_copy.ivar + assert_equal obj.member, obj_copy.member + refute_same obj.member, obj_copy.member + RUBY + end + def test_fork_raise_isolation_error assert_ractor(<<~'RUBY') ractor = Ractor.new do |
