diff options
author | Alan Wu <[email protected]> | 2024-10-11 10:22:44 -0400 |
---|---|---|
committer | GitHub <[email protected]> | 2024-10-11 10:22:44 -0400 |
commit | 11e7ab79deb5935573d15ba4f33fc41e5c2b7522 (patch) | |
tree | 1cfc9e22733dc2f097db6fda74539feb014fe411 /enum.c | |
parent | 372bb990ac5ea8e348b9187b53d108d06049e6a3 (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.c | 14 |
1 files changed, 5 insertions, 9 deletions
@@ -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; } |