Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RubyKaigi Dev Meeting 2025

RubyKaigi Dev Meeting 2025

Aaron Patterson

April 15, 2025
Tweet

More Decks by Aaron Patterson

Other Decks in Programming

Transcript

  1. Implement Class#new in Ruby class Class def new(...) Primitive.attr! :c_trace

    Primitive.pop!( Primitive.send_delegate!( Primitive.dup!(Primitive.rb_class_alloc2), :initialize, ...)) end end class BasicObject def initialize Primitive.attr! :c_trace nil end end
  2. Before > ruby --dump=insns -e'Object.new' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,10)> 0000

    opt_getconstant_path <ic:0 Object> ( 1)[Li] 0002 opt_send_without_block <calldata!mid:new, argc:0, ARGS_SIMPLE> 0004 leave
  3. After > ./miniruby --dump=insns -e'Object.new' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,10)> 0000

    opt_getconstant_path <ic:0 Object> ( 1)[Li] 0002 putnil 0003 swap 0004 opt_new <calldata!mid:new, argc:0, ARGS_SIMPLE>, 11 0007 opt_send_without_block <calldata!mid:initialize, argc:0, FCALL|ARGS_SIMPLE> 0009 jump 14 0011 opt_send_without_block <calldata!mid:new, argc:0, ARGS_SIMPLE> 0013 swap 0014 pop 0015 leave
  4. Positional Parameters Allocations per Second by Ruby version Allocations Per

    Second 0 9500000 19000000 28500000 38000000 Number of Parameters 0 1 2 3 4 5 6 7 8 9 10 Ruby 3.5 + inlining Ruby 3.4
  5. Keyword Parameters Allocations per second by Ruby version Allocations Per

    Second 0 10000000 20000000 30000000 40000000 Number of Parameters 0 1 2 3 4 5 6 7 8 9 10 Ruby 3.5+inlining Ruby 3.4
  6. Positional Parameters + Varied Classes Allocations per second by Ruby

    version
 (varying allocated class) Allocations per Second 0 9500000 19000000 28500000 38000000 Number of Parameters 0 1 2 3 4 5 6 7 8 9 10 Ruby 3.5+Inlining Ruby 3.4
  7. Keyword Parameters + Varied Classes Allocations per second by Ruby

    version
 (varying allocated class) Allocations Per Second 0 10000000 20000000 30000000 40000000 Number of Parameters 0 1 2 3 4 5 6 7 8 9 10 Ruby 3.5+Inlining Ruby 3.4
  8. Measure ISeq size How many bytes does the “alloc” method

    use? require "objspace" def alloc Object.new end m = method(:alloc) insn = RubyVM::InstructionSequence.of(insn) puts ObjectSpace.memsize_of(insn) Ruby 3.5 + inlining: 656 bytes Ruby 3.4: 544 bytes +122 Bytes
  9. Real World Memory Increase (ISeq Only) 0.5% Increase in ISeq

    Size (Ruby 3.4.2 vs 3.5.0+inline) irb(main):001> 737191972 - 733354388 => 3837584 Shopify M onolith ISeq Sizes
  10. Real World Memory Increase (all memory) 1mb increase total (~4GB

    heap) irb(main):001> 3981075617 - 3979926505 => 1149112 Shopify M onolith Total H eap
  11. Stack Trace is Different Class#new is missing class Foo def

    initialize puts caller end end def hello Foo.new end hello > ruby test.rb test.rb:8:in 'Class#new' test.rb:8:in 'Object#hello' test.rb:11:in '<main>' Ruby 3.4 > ./ruby test.rb test.rb:8:in 'Object#hello' test.rb:11:in '<main>' Ruby 3.5 + inlining