Bug #9382

[patch] add opt_aref_str and opt_aset_str

Added by Aman Gupta over 1 year ago. Updated about 1 year ago.

[ruby-core:59640]
Status:Closed
Priority:Normal
Assignee:Aman Gupta
ruby -v:trunk Backport:1.9.3: DONTNEED, 2.0.0: DONTNEED, 2.1: DONTNEED

Description

@charliesome, @normalperson 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

After:

0010 opt_aref_str , "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 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.


Related issues

Related to Ruby trunk - Feature #8998: string keys for hash literals should use fstrings Closed 10/08/2013
Related to Ruby trunk - Misc #9188: r43870 make benchmark/bm_so_k_nucleotide.rb slow Closed 12/01/2013

Associated revisions

Revision 44551
Added by Aman Gupta over 1 year ago

insns.def: add opt path for Hash#[] and Hash#[]= used with str literal keys

  • insns.def (opt_aref_with): new instruction to optimize Hash#[], removing any allocation overhead when used with a string literal key. Patch by normalperson (Eric Wong). [Bug #9382]
  • insns.def (opt_aset_with): new instruction to optimize Hash#[]=
  • compile.c (iseq_compile_each): compiler shortcuts for new instructions
  • hash.c (static VALUE rb_hash_compare_by_id_p): fix documentation for Hash#compare_by_identity to reflect frozen string sharing
  • test/ruby/test_hash.rb (class TestHash): test for new behavior

Revision 44551
Added by Aman Gupta over 1 year ago

insns.def: add opt path for Hash#[] and Hash#[]= used with str literal keys

  • insns.def (opt_aref_with): new instruction to optimize Hash#[], removing any allocation overhead when used with a string literal key. Patch by normalperson (Eric Wong). [Bug #9382]
  • insns.def (opt_aset_with): new instruction to optimize Hash#[]=
  • compile.c (iseq_compile_each): compiler shortcuts for new instructions
  • hash.c (static VALUE rb_hash_compare_by_id_p): fix documentation for Hash#compare_by_identity to reflect frozen string sharing
  • test/ruby/test_hash.rb (class TestHash): test for new behavior

History

#1 Updated by Aman Gupta over 1 year ago

With the patch, "allocations per request" in our app is reduced by ~3%.

#2 Updated by Nobuyoshi Nakada about 1 year ago

  • Backport changed from 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: UNKNOWN to 1.9.3: DONTNEED, 2.0.0: DONTNEED, 2.1: DONTNEED
  • Status changed from Open to Closed

Also available in: Atom PDF