mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
enum.c: make each_slice and each_cons more efficient
* enum.c (enum_each_slice, enum_each_cons): make more efficient by allocating less and recycling block argument arrays if possible. [Fixes GH-596] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45589 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
70cbe70b71
commit
20675167d7
2 changed files with 26 additions and 4 deletions
|
@ -1,3 +1,9 @@
|
|||
Tue Apr 15 12:49:53 2014 Sam Rawlins <sam.rawlins@gmail.com>
|
||||
|
||||
* enum.c (enum_each_slice, enum_each_cons): make more efficient by
|
||||
allocating less and recycling block argument arrays if possible.
|
||||
[Fixes GH-596]
|
||||
|
||||
Mon Apr 14 18:44:45 2014 NARUSE, Yui <naruse@ruby-lang.org>
|
||||
|
||||
* addr2line.c (fill_lines): get base addrs in fill_lines to use it
|
||||
|
|
24
enum.c
24
enum.c
|
@ -2058,6 +2058,9 @@ enum_each_entry(int argc, VALUE *argv, VALUE obj)
|
|||
return obj;
|
||||
}
|
||||
|
||||
#define dont_recycle_block_arg(arity) ((arity) == 1 || (arity) == -1)
|
||||
#define nd_no_recycle u2.value
|
||||
|
||||
static VALUE
|
||||
each_slice_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, m))
|
||||
{
|
||||
|
@ -2071,7 +2074,13 @@ each_slice_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, m))
|
|||
|
||||
if (RARRAY_LEN(ary) == size) {
|
||||
v = rb_yield(ary);
|
||||
memo->u1.value = rb_ary_new2(size);
|
||||
|
||||
if (memo->nd_no_recycle) {
|
||||
memo->u1.value = rb_ary_new2(size);
|
||||
}
|
||||
else {
|
||||
rb_ary_clear(ary);
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
|
@ -2113,11 +2122,13 @@ enum_each_slice(VALUE obj, VALUE n)
|
|||
long size = NUM2LONG(n);
|
||||
VALUE ary;
|
||||
NODE *memo;
|
||||
int arity;
|
||||
|
||||
if (size <= 0) rb_raise(rb_eArgError, "invalid slice size");
|
||||
RETURN_SIZED_ENUMERATOR(obj, 1, &n, enum_each_slice_size);
|
||||
ary = rb_ary_new2(size);
|
||||
memo = NEW_MEMO(ary, 0, size);
|
||||
arity = rb_block_arity();
|
||||
memo = NEW_MEMO(ary, dont_recycle_block_arg(arity), size);
|
||||
rb_block_call(obj, id_each, 0, 0, each_slice_i, (VALUE)memo);
|
||||
ary = memo->u1.value;
|
||||
if (RARRAY_LEN(ary) > 0) rb_yield(ary);
|
||||
|
@ -2139,7 +2150,10 @@ each_cons_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
|
|||
}
|
||||
rb_ary_push(ary, i);
|
||||
if (RARRAY_LEN(ary) == size) {
|
||||
v = rb_yield(rb_ary_dup(ary));
|
||||
if (memo->nd_no_recycle) {
|
||||
ary = rb_ary_dup(ary);
|
||||
}
|
||||
v = rb_yield(ary);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
@ -2184,10 +2198,12 @@ enum_each_cons(VALUE obj, VALUE n)
|
|||
{
|
||||
long size = NUM2LONG(n);
|
||||
NODE *memo;
|
||||
int arity;
|
||||
|
||||
if (size <= 0) rb_raise(rb_eArgError, "invalid size");
|
||||
RETURN_SIZED_ENUMERATOR(obj, 1, &n, enum_each_cons_size);
|
||||
memo = NEW_MEMO(rb_ary_new2(size), 0, size);
|
||||
arity = rb_block_arity();
|
||||
memo = NEW_MEMO(rb_ary_new2(size), dont_recycle_block_arg(arity), size);
|
||||
rb_block_call(obj, id_each, 0, 0, each_cons_i, (VALUE)memo);
|
||||
|
||||
return Qnil;
|
||||
|
|
Loading…
Add table
Reference in a new issue