From 11e7ab79deb5935573d15ba4f33fc41e5c2b7522 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Fri, 11 Oct 2024 10:22:44 -0400 Subject: Remove 1 allocation in Enumerable#each_with_index (#11868) * Remove 1 allocation in Enumerable#each_with_index Previously, each call to Enumerable#each_with_index allocates 2 objects, one for the counting index, the other an imemo_ifunc passed to `self.each` as a block. Use `struct vm_ifunc::data` to hold the counting index directly to remove 1 allocation. * [DOC] Brief summary for usages of `struct vm_ifunc` --- enum.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'enum.c') diff --git a/enum.c b/enum.c index 6aec34d850..d8a7cb73f3 100644 --- a/enum.c +++ b/enum.c @@ -2984,13 +2984,12 @@ enum_member(VALUE obj, VALUE val) } static VALUE -each_with_index_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memo)) +each_with_index_i(RB_BLOCK_CALL_FUNC_ARGLIST(_, index)) { - struct MEMO *m = MEMO_CAST(memo); - VALUE n = imemo_count_value(m); + struct vm_ifunc *ifunc = rb_current_ifunc(); + ifunc->data = (const void *)rb_int_succ(index); - imemo_count_up(m); - return rb_yield_values(2, rb_enum_values_pack(argc, argv), n); + return rb_yield_values(2, rb_enum_values_pack(argc, argv), index); } /* @@ -3024,12 +3023,9 @@ each_with_index_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, memo)) static VALUE enum_each_with_index(int argc, VALUE *argv, VALUE obj) { - struct MEMO *memo; - RETURN_SIZED_ENUMERATOR(obj, argc, argv, enum_size); - memo = MEMO_NEW(0, 0, 0); - rb_block_call(obj, id_each, argc, argv, each_with_index_i, (VALUE)memo); + rb_block_call(obj, id_each, argc, argv, each_with_index_i, INT2FIX(0)); return obj; } -- cgit v1.2.3