diff options
author | Alan Wu <[email protected]> | 2021-05-26 11:50:37 -0400 |
---|---|---|
committer | Alan Wu <[email protected]> | 2021-05-28 12:34:03 -0400 |
commit | 5ada23ac1265a1da5d7ef82e1c71f14c40dddc26 (patch) | |
tree | e6a39d25c08063c2bfcbc9cb9d153daf69b1f047 /compile.c | |
parent | 788d30a8b388cd5500862a4015537203ef49ea85 (diff) |
compile.c: Emit send for === calls in when statements
The checkmatch instruction with VM_CHECKMATCH_TYPE_CASE calls
=== without a call cache. Emit a send instruction to make the call
instead. It includes a call cache.
The call cache improves throughput of using when statements to check the
class of a given object. This is useful for say, JSON serialization.
Use of a regular send instead of checkmatch also avoids taking the VM
lock every time, which is good for multi-ractor workloads.
Calculating -------------------------------------
master post
vm_case_classes 11.013M 16.172M i/s - 6.000M times in 0.544795s 0.371009s
vm_case_lit 2.296 2.263 i/s - 1.000 times in 0.435606s 0.441826s
vm_case 74.098M 64.338M i/s - 6.000M times in 0.080974s 0.093257s
Comparison:
vm_case_classes
post: 16172114.4 i/s
master: 11013316.9 i/s - 1.47x slower
vm_case_lit
master: 2.3 i/s
post: 2.3 i/s - 1.01x slower
vm_case
master: 74097858.6 i/s
post: 64338333.9 i/s - 1.15x slower
The vm_case benchmark is a bit slower post patch, possibily due to the
larger instruction sequence. The benchmark dispatches using
opt_case_dispatch so was not running checkmatch and does not make the
=== call post patch.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/4468
Diffstat (limited to 'compile.c')
-rw-r--r-- | compile.c | 6 |
1 files changed, 3 insertions, 3 deletions
@@ -4572,8 +4572,6 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals, rb_hash_aset(literals, lit, (VALUE)(l1) | 1); } - ADD_INSN(cond_seq, val, dup); /* dup target */ - if (nd_type(val) == NODE_STR) { debugp_param("nd_lit", val->nd_lit); lit = rb_fstring(val->nd_lit); @@ -4584,7 +4582,9 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals, if (!COMPILE(cond_seq, "when cond", val)) return -1; } - ADD_INSN1(cond_seq, vals, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE)); + // Emit patern === target + ADD_INSN1(cond_seq, vals, topn, INT2FIX(1)); + ADD_CALL(cond_seq, vals, idEqq, INT2FIX(1)); ADD_INSNL(cond_seq, val, branchif, l1); vals = vals->nd_next; } |