summaryrefslogtreecommitdiff
path: root/enum.c
diff options
context:
space:
mode:
authorAlan Wu <[email protected]>2024-10-11 10:22:44 -0400
committerGitHub <[email protected]>2024-10-11 10:22:44 -0400
commit11e7ab79deb5935573d15ba4f33fc41e5c2b7522 (patch)
tree1cfc9e22733dc2f097db6fda74539feb014fe411 /enum.c
parent372bb990ac5ea8e348b9187b53d108d06049e6a3 (diff)
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`
Notes
Notes: Merged-By: maximecb <[email protected]>
Diffstat (limited to 'enum.c')
-rw-r--r--enum.c14
1 files changed, 5 insertions, 9 deletions
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;
}