From: "byroot (Jean Boussier) via ruby-core" Date: 2023-02-10T20:34:11+00:00 Subject: [ruby-core:112349] [Ruby master Bug#19424] Significant performance decreases in `OpenStruct#marshal_load` in Ruby 3.0 and 3.1 Issue #19424 has been updated by byroot (Jean Boussier). Yes, I'm trying to pinpoint the change that made the eager definition of these methods, to try to figure out the rationale. That said I'm doing so purely for curiosity, where I stand `OpenStruct` is fine quick mocks and such, but it can't possibly have decent performance. So between slow and slower... ---------------------------------------- Bug #19424: Significant performance decreases in `OpenStruct#marshal_load` in Ruby 3.0 and 3.1 https://bugs.ruby-lang.org/issues/19424#change-101793 * 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** ![](Screenshot 2023-02-07 at 1.04.49 PM.png) ---Files-------------------------------- Screenshot 2023-02-07 at 1.04.49 PM.png (184 KB) -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/