ruby-changes:50298
From: nobu <ko1@a...>
Date: Thu, 15 Feb 2018 19:01:03 +0900 (JST)
Subject: [ruby-changes:50298] nobu:r62413 (trunk): Array#values_at optimization
nobu 2018-02-15 19:00:57 +0900 (Thu, 15 Feb 2018) New Revision: 62413 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62413 Log: Array#values_at optimization * array.c (rb_ary_values_at): optimization range argument case. bulk concatenation than pushing for each element. Modified files: trunk/array.c Index: array.c =================================================================== --- array.c (revision 62412) +++ array.c (revision 62413) @@ -2804,6 +2804,34 @@ rb_get_values_at(VALUE obj, long olen, i https://github.com/ruby/ruby/blob/trunk/array.c#L2804 return result; } +static VALUE +append_values_at_single(VALUE result, VALUE ary, long olen, VALUE idx) +{ + long beg, len; + if (FIXNUM_P(idx)) { + beg = FIX2LONG(idx); + } + /* check if idx is Range */ + else if (rb_range_beg_len(idx, &beg, &len, olen, 1)) { + if (len > 0) { + const VALUE *const src = RARRAY_CONST_PTR(ary); + const long end = beg + len; + const long prevlen = RARRAY_LEN(result); + if (beg < olen) { + rb_ary_cat(result, src + beg, end > olen ? olen-beg : len); + } + if (end > olen) { + rb_ary_store(result, prevlen + len - 1, Qnil); + } + } + return result; + } + else { + beg = NUM2LONG(idx); + } + return rb_ary_push(result, rb_ary_entry(ary, beg)); +} + /* * call-seq: * ary.values_at(selector, ...) -> new_ary @@ -2825,7 +2853,13 @@ rb_get_values_at(VALUE obj, long olen, i https://github.com/ruby/ruby/blob/trunk/array.c#L2853 static VALUE rb_ary_values_at(int argc, VALUE *argv, VALUE ary) { - return rb_get_values_at(ary, RARRAY_LEN(ary), argc, argv, rb_ary_entry); + long i, olen = RARRAY_LEN(ary); + VALUE result = rb_ary_new_capa(argc); + for (i = 0; i < argc; ++i) { + append_values_at_single(result, ary, olen, argv[i]); + } + RB_GC_GUARD(ary); + return result; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/