Issue #9227 has been updated by tmm1 (Aman Gupta).


I did some more microbenchmarks. In the Array#[Fixnum]= case, the new instruction makes a huge difference.

Before:
array aset             1.430000   0.000000   1.430000 (  1.430370)
array aset             1.430000   0.000000   1.430000 (  1.429422)
array aset             1.520000   0.000000   1.520000 (  1.544912)
array aset             1.440000   0.000000   1.440000 (  1.444454)

After:
array aset             0.910000   0.000000   0.910000 (  0.908866)
array aset             0.910000   0.000000   0.910000 (  0.910356)
array aset             0.890000   0.000000   0.890000 (  0.891267)
array aset             0.920000   0.000000   0.920000 (  0.921012)

Benchmark:

require 'benchmark'
Benchmark.bmbm(20) do |b|
  ary = [1,2,3,4]
  b.report('array aset') do
    10_000_000.times do
      ary[2] = 2
      ary[3] = 3
    end
  end
end

Here's a copy of the patch that applies on trunk:

diff --git a/compile.c b/compile.c
index af11baf..25e3652 100644
--- a/compile.c
+++ b/compile.c
@@ -1955,6 +1955,11 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
 		  case idAREF:	 SP_INSN(aref);	  return COMPILE_OK;
 		}
 		break;
+	      case 2:
+		switch (ci->mid) {
+		  case idASET:	 SP_INSN(aset);	  return COMPILE_OK;
+		}
+		break;
 	    }
 	}
 	if (ci->flag & VM_CALL_ARGS_SKIP_SETUP) {

----------------------------------------
Bug #9227: use opt_aset ?
https://bugs.ruby-lang.org/issues/9227#change-43596

Author: tmm1 (Aman Gupta)
Status: Open
Priority: Normal
Assignee: ko1 (Koichi Sasada)
Category: 
Target version: current: 2.1.0
ruby -v: trunk
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN


I noticed we have an opt_aset instruction, but nothing is using it. Is there some reason?

diff --git a/compile.c b/compile.c
index 812f692..9d9f14f 100644
--- a/compile.c
+++ b/compile.c
@@ -1955,6 +1955,11 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
                  case idAREF:   SP_INSN(aref);   return COMPILE_OK;
                }
                break;
+             case 2:
+               switch (ci->mid) {
+                   case idASET: SP_INSN(aset);   return COMPILE_OK;
+               }
+               break;
            }
        }
        if (ci->flag & VM_CALL_ARGS_SKIP_SETUP) {


-- 
http://bugs.ruby-lang.org/