Bug #9382
closed[patch] add opt_aref_str and opt_aset_str
Description
@charliesome, @normalperson (Eric Wong) and I have been working on a patch to add two new instructions:
https://bugs.ruby-lang.org/issues/9188#note-9
These optimize Hash#[] and Hash#[]=, when used with a string literal key.
Before:
0010 putstring "str"
0012 opt_aref <callinfo!mid:[], argc:1, ARGS_SKIP>
After:
0010 opt_aref_str <callinfo!mid:[], argc:1, ARGS_SKIP>, "str"
The opt_(aref|aset)_str instructions avoid str_duplicate, resulting in reduced allocation overhead. For example, this loop requires zero allocations after the patch:
hash={}; loop{ hash["key"] += 1 }
In our rails app, 2.5% of iseqs can benefit from these optimizations:
$ ruby -rconfig/environment -e' p ObjectSpace.each_object(RubyVM::InstructionSequence).count '
63314
$ ruby -rconfig/environment -e' p ObjectSpace.each_object(RubyVM::InstructionSequence).select{ |i| i.disasm.match(/ opt_(aref|aset)_str /) }.size '
1464
@headius (Charles Nutter) is also adding a similar optimization to jruby: https://bugs.ruby-lang.org/issues/8998#note-15
I plan to commit the patch above, so if you have any feedback on the implementation please share.