1
0
Fork 0
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:
nobu 2014-04-15 03:49:55 +00:00
parent 70cbe70b71
commit 20675167d7
2 changed files with 26 additions and 4 deletions

View file

@ -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
View file

@ -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;