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

Hacking Ruby

Hacking Ruby

I stayed up way too late and decided to hack Ruby's C code.

Lightning talk prepared for MountainWest RubyConf 2013.

pete higgins

April 05, 2013
Tweet

More Decks by pete higgins

Other Decks in Programming

Transcript

  1. Me

  2. Old & Busted static VALUE rb_ary_collect(VALUE ary) { long i;

    VALUE collect; RETURN_SIZED_ENUMERATOR(ary, 0, 0, rb_ary_length); collect = rb_ary_new2(RARRAY_LEN(ary)); for (i = 0; i < RARRAY_LEN(ary); i++) { rb_ary_push(collect, rb_yield(RARRAY_PTR(ary)[i])); } return collect; }
  3. New Hotness static VALUE rb_ary_collect(int argc, VALUE *argv, VALUE ary)

    { /* ... */ if (rb_scan_args(argc, argv, "01", &op) > 0) { id = rb_check_id(&op); for (i = 0; i < RARRAY_LEN(ary); i++) { rb_ary_push(collect, rb_funcall(RARRAY_PTR(ary)[i], id, 0)); } } /* ... */
  4. Benchmark! require 'benchmark' a = (0..10).to_a n = ARGV.first ||

    1_000_000 Benchmark.bmbm do |b| b.report("nil") { n.times { nil } } b.report("identity") { n.times { a.map {|i| i } } } b.report("block") { n.times { a.map {|i| i.to_i } } } b.report("to_proc") { n.times { a.map(&:to_i) } } # b.report("symbol") { n.times { a.map(:to_i) } } end
  5. Benchmark! $ ./ruby -I. -Ilib/ -w map_symbol_bench.rb Rehearsal -------------------------------------------- nil

    0.050000 0.000000 0.050000 ( 0.046891) identity 0.880000 0.000000 0.880000 ( 0.887874) block 1.080000 0.000000 1.080000 ( 1.078556) to_proc 0.990000 0.000000 0.990000 ( 0.996956) ----------------------------------- total: 3.000000sec user system total real nil 0.040000 0.000000 0.040000 ( 0.045237) identity 0.860000 0.000000 0.860000 ( 0.866740) block 1.070000 0.000000 1.070000 ( 1.066750) to_proc 0.990000 0.000000 0.990000 ( 0.986012)
  6. Benchmark! II require 'benchmark' a = (0..10).to_a n = ARGV.first

    || 1_000_000 Benchmark.bmbm do |b| b.report("nil") { n.times { nil } } b.report("identity") { n.times { a.map {|i| i } } } b.report("block") { n.times { a.map {|i| i.to_i } } } b.report("to_proc") { n.times { a.map(&:to_i) } } b.report("symbol") { n.times { a.map(:to_i) } } end
  7. Benchmark! II $ ./ruby -I. -Ilib/ -w map_symbol_bench.rb Rehearsal --------------------------------------------

    nil 0.050000 0.000000 0.050000 ( 0.044915) identity 0.920000 0.010000 0.930000 ( 0.928270) block 1.080000 0.000000 1.080000 ( 1.078040) to_proc 0.980000 0.000000 0.980000 ( 0.983513) symbol 0.700000 0.000000 0.700000 ( 0.701426) ----------------------------------- total: 3.740000sec user system total real nil 0.050000 0.000000 0.050000 ( 0.044602) identity 0.880000 0.000000 0.880000 ( 0.890868) block 1.080000 0.000000 1.080000 ( 1.076316) to_proc 0.980000 0.000000 0.980000 ( 0.984099) symbol 0.700000 0.000000 0.700000 ( 0.703862)