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

Improving my own Ruby thereafter

Improving my own Ruby thereafter

presentation material for RubyKaigi2025 follow up.
https://rhc.connpass.com/event/356128/

Avatar for monochrome

monochrome

August 31, 2025
Tweet

More Decks by monochrome

Other Decks in Programming

Transcript

  1. monoruby - https://github.com/sisshiki1969/monoruby - A yet another Ruby implementation with

    JIT compiler - Written in Rust from (almost) scratch - parser, garbage collector, interpreter - Only x86-64 / Linux is supported - new! Supports RubyGems. - not yet! Struggling with Bundler.
  2. So You Want To Optimize Ruby • Fixnum to Bignum

    promotion • Floating-point performance • Closures • Method invalidation • Constant lookup and invalidation • Bindings and eval • Fiber implementation • Garbage collection and object allocation by Charles Nutter Oct 15, 2012
  3. So You Want To Optimize Ruby • C extension support

    • Ruby 1.9 encoding support • Concurrency / Parallelism • Tracing/debugging • ObjectSpace • Rails by Charles Nutter Oct 15, 2012
  4. Support RubyGems/Bundler - a lot of metaprogramming method_missing, method_added -

    ancient syntax =begin the everything between a line beginning with `=begin' and that with `=end' will be skipped by the interpreter. =end - weird method definition def f(a, b, c, m = 1, n = 1, *rest, x, y, z, k: 1, **kwrest, &blk) end
  5. Suuport RubyGems/Bundler - Regular expression class (Regexp) • Used to

    be: Rust library(fancy-regex crate) • However ... ◦ ASCII-8BIT is not supported ◦ Comments in free-format mode(/x) does not work • Moved to Onigmo
  6. Specialization “generic” Array#each ary.each do |i| puts i end do

    |i| puts i end ary.each do |x,y| x + y end do |x,y| x + y end ary.each.flat_map class Array def each .. yield .. end end We don’t know until runtime: 1. which block is given (or not given) 2. a signature of given block
  7. compile at one time Specialization “specialized” Array#each ary.each do |i|

    puts i end do |i| puts i end class Array def each .. yield .. end end
  8. class Array def each return self.to_enum(:each) if !block_given? i =

    0 while i < self.size yield self[i] i += 1 end self end end Array#each
  9. BB 0 :00000 init_method :00001 %3 = %0.block_given?() [Array] FuncId(74)

    :00003 %2 = %3 :00004 %2 = !%2 :00005 condnotbr %2 => BB2 BB 1 :00006 %2 = :each :00007 %2 = %0.to_enum(%2) :00009 ret %2 BB 2 :00010 %1 = 0: i32 BB 3 :00011 loop_start :00012 %2 = %0.size() [Array] FuncId(249) :00014 _%2 = %1 < %2 [Integer][Integer] :00015 condnotbr _%2 => BB5 BB 4 :00016 %2 = %0.[%1] [Array][Integer] :00017 _ = yield(%2) :00019 %1 = %1 + 1: i16 [Integer][Integer] :00020 br => BB3 BB 5 :00021 loop_end BB 6 :00022 ret %0 we can remove this branch in this specialized context, always true asm inlined asm inlined Now we know the block to be called