summaryrefslogtreecommitdiff
path: root/variable.c
diff options
context:
space:
mode:
authorPeter Zhu <[email protected]>2022-11-17 09:47:18 -0500
committerPeter Zhu <[email protected]>2022-11-21 10:22:29 -0500
commit1f0888ab3e699a1083cddad84b0d8cb28e15ad8e ()
tree425b56eb1418cf8324f25d7d0cb4f7ff887183ed /variable.c
parent648927d71bde5df02a0490f5f45bb7fcde913376 (diff)
Speed up shape transitions
This commit significantly speeds up shape transitions as it changes get_next_shape_internal to not perform a lookup (and instead require the caller to perform the lookup). This avoids double lookups during shape transitions. There is a significant (~2x) speedup in the following micro-benchmark: puts(Benchmark.measure do o = Object.new 100_000.times do |i| o.instance_variable_set(:"@a#{i}", 0) end end) Before: 22.393194 0.201639 22.594833 ( 22.684237) After: 11.323086 0.022284 11.345370 ( 11.389346)
Notes: Merged: https://.com/ruby/ruby/pull/6751
-rw-r--r--variable.c25
1 files changed, 15 insertions, 10 deletions
@@ -1276,28 +1276,33 @@ static void
generic_ivar_set(VALUE obj, ID id, VALUE val)
{
struct ivar_update ivup;
// The returned shape will have `id` in its iv_table
- rb_shape_t * shape = rb_shape_get_next(rb_shape_get_shape(obj), obj, id);
ivup.shape = shape;
RB_VM_LOCK_ENTER();
{
- attr_index_t ent_data;
- if (rb_shape_get_iv_index(shape, id, &ent_data)) {
- ivup.iv_index = (uint32_t) ent_data;
- }
- else {
- rb_bug("unreachable. Shape was not found for id: %s", rb_id2name(id));
- }
st_update(generic_ivtbl(obj, id, false), (st_data_t)obj, generic_ivar_update, (st_data_t)&ivup);
}
RB_VM_LOCK_LEAVE();
ivup.ivtbl->ivptr[ivup.iv_index] = val;
-
- rb_shape_set_shape(obj, shape);
RB_OBJ_WRITTEN(obj, Qundef, val);
}
static VALUE *