
Issue #19424 has been updated by jeremyevans0 (Jeremy Evans). jeremyevans0 (Jeremy Evans) wrote in #note-4:
So part of the issue is `ostruct` (due to the commit mentioned), and part of the issue appears to be `Marshal.load` changes in 3.0.
Well, not `Marshal.load`, but the initialization approach `ostruct` switched to became slower in Ruby 3.0. New benchmark: ```ruby require 'benchmark' gem 'ostruct' require 'ostruct' p ["OpenStruct::VERSION", OpenStruct::VERSION] n = 100_000 obj = OpenStruct.new( one: nil ) Benchmark.bm(20) do |x| klass = obj.class x.report("#{klass} dump") do n.times do Marshal.dump(obj) end end m = Marshal.dump(obj) x.report("#{klass} load") do n.times do Marshal.load(m) end end x.report("#{klass} new") do n.times do OpenStruct.new( one: nil ) end end end ``` output: ``` ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5) [x86_64-openbsd] ["OpenStruct::VERSION", "0.5.5"] user system total real OpenStruct dump 0.510000 0.010000 0.520000 ( 0.518952) OpenStruct load 1.390000 0.000000 1.390000 ( 1.389447) OpenStruct new 1.000000 0.000000 1.000000 ( 1.016224) ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c5) [x86_64-openbsd] ["OpenStruct::VERSION", "0.5.5"] user system total real OpenStruct dump 0.520000 0.000000 0.520000 ( 0.537284) OpenStruct load 2.190000 0.000000 2.190000 ( 2.191907) OpenStruct new 1.680000 0.000000 1.680000 ( 1.679188) ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e) [x86_64-openbsd] ["OpenStruct::VERSION", "0.5.5"] user system total real OpenStruct dump 0.580000 0.000000 0.580000 ( 0.562538) OpenStruct load 2.210000 0.000000 2.210000 ( 2.242819) OpenStruct new 1.650000 0.000000 1.650000 ( 1.672738) ``` ---------------------------------------- Bug #19424: Significant performance decreases in `OpenStruct#marshal_load` in Ruby 3.0 and 3.1 https://bugs.ruby-lang.org/issues/19424#change-101791 * Author: sumitdey035 (Sumit Dey) * Status: Open * Priority: Normal * ruby -v: 3.1.2 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- I can see degradation in **Marshal load** only in Ruby 3.1.2 compared to 2.7.4 Processing time increased by 200%(2.4 sec to 4.3 sec) Memory allocation increased by 600%(6500001 to 39000004) ``` require 'benchmark' require 'ostruct' N_OJ = 500_000 ex_HASH = { 'one' => 1, 'array' => [ true, false ] } ex_JSON = '{ "one": 1, "array": [ true, false ] }' ex_STRUCT = OpenStruct.new( one: 1, hash: ex_HASH, array: [ true, false ] ) ex_MARSHAL = "\x04\bU:\x0FOpenStruct{\b:\bonei\x06:\thash{\aI\"\bone\x06:\x06ETi\x06I\"\narray\x06;\bT[\aTF:\narray[\aTF" "-----------------Ruby #{system("rbenv version")}----------------" Benchmark.bm(20) do |x| x.report('native marshal dump') do N_OJ.times do y = Marshal.dump(ex_STRUCT) end end x.report('native marshal load') do N_OJ.times do y = Marshal.load(ex_MARSHAL) end end start_memory = GC.stat[:total_allocated_objects] N_OJ.times do y = Marshal.dump(ex_STRUCT) end end_memory = GC.stat[:total_allocated_objects] print "Marshal dump memory allocation- #{end_memory - start_memory}\n" start_memory = GC.stat[:total_allocated_objects] N_OJ.times do y = Marshal.load(ex_MARSHAL) end end_memory = GC.stat[:total_allocated_objects] print "Marshal load memory allocation- #{end_memory - start_memory}\n" end``` **Benchmark and Memory consumption result**  ---Files-------------------------------- Screenshot 2023-02-07 at 1.04.49 PM.png (184 KB) -- https://bugs.ruby-lang.org/