poor man's rubyの高速化検討

デバッグしないといけないが、つい楽しい方に流れてしまいます。そういうことで、minilightを実行したときのプロファイルをとってみました。

$ gprof /usr/local/bin/static-poorruby 
Flat profile:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total           
 time   seconds   seconds    calls   s/call   s/call  name    
 47.32     25.89    25.89 23614523     0.00     0.00  vm_eval
 10.73     31.76     5.87 341352557     0.00     0.00  vm_call_method
  5.85     34.96     3.20 280054830     0.00     0.00  st_lookup
  2.89     36.54     1.58 29970662     0.00     0.00  rb_obj_is_kind_of
  2.76     38.05     1.51 227602589     0.00     0.00  ivar_get
  2.41     39.37     1.32 195429335     0.00     0.00  call_cfunc
  1.86     40.39     1.02 416832029     0.00     0.00  rb_value2float
  1.74     41.34     0.95     4016     0.00     0.00  garbage_collect
  1.48     42.15     0.81 221254551     0.00     0.00  rb_float_new
  1.48     42.96     0.81 49644558     0.00     0.00  rb_ivar_set
  1.21     43.62     0.66 23379932     0.00     0.00  vm_call0
  1.12     44.23     0.62 32737159     0.00     0.00  flo_mul
  1.06     44.81     0.58 15285417     0.00     0.00  gc_mark_children
  0.93     45.32     0.51 227602588     0.00     0.00  rb_ivar_get
  0.87     45.80     0.48 21671859     0.00     0.00  ruby_xmalloc2
  0.86     46.27     0.47 300596085     0.00     0.00  rb_class_real
  0.84     46.73     0.46 10832046     0.00     0.00  invoke_block
  0.82     47.18     0.45 288924709     0.00     0.00  rb_obj_class
  0.79     47.61     0.43 19588028     0.00     0.00  flo_minus
  0.77     48.03     0.42  3735017     0.00     0.00  st_foreach
  0.69     48.41     0.38 74475435     0.00     0.00  gc_mark
  0.68     48.78     0.37 73635164     0.00     0.00  rb_newobj
  0.58     49.10     0.32 114052865     0.00     0.00  rb_method_node
  0.55     49.40     0.30 22478300     0.00     0.00  vm_eval_body
  0.53     49.69     0.29 47689038     0.00     0.00  vm_callee_setup_arg
  0.51     49.97     0.28 12714828     0.00     0.00  flo_lt
  0.42     50.20     0.23 77792149     0.00     0.00  rb_ary_entry
  0.42     50.43     0.23 14353194     0.00     0.00  flo_plus
  0.37     50.63     0.20 23379932     0.00     0.00  rb_call0
  0.37     50.83     0.20                             vm_invoke_proc
  0.29     50.99     0.16 122467360     0.00     0.00  rb_safe_level
  0.27     51.14     0.15   207314     0.00     0.00  flo_div
  0.26     51.28     0.14      953     0.00     0.00  new_size
  0.24     51.41     0.13 21664583     0.00     0.00  rb_ary_new4
  0.22     51.53     0.12    16064     0.00     0.00  mark_locations_array
  0.21     51.64     0.12 23379932     0.00     0.00  rb_call
  0.21     51.76     0.12 21679603     0.00     0.00  ruby_xmalloc
  0.21     51.87     0.12                             num_int_p

以下略

これをみて思ったこと

  1. vm_evalで半分、実行時間を費やしています。opt_plusとかopt_minusとかをチューンする必要がありそうです
  2. rb_value2floatやrb_float_newが結構時間をとっています。インライン化を検討すべきです
  3. 最終的にはvm_evalのオーバヘッドを究極まで減らすためにJIT化かなー...
  4. GC結構起動されていますね。メモリのアロケーション状況をみてみる必要がありそうです。
  5. flo_何とか(flo_plusとか)が結構呼ばれています。整数との演算かなー?調べる必要がありそうです。
  6. 0に極めて近い数はヒープにとっていますが、RVALUEにとるようにしたほうがいいのかなー?