mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Improved Enumerable::Lazy#zip
| |compare-ruby|built-ruby| |:-------------------|-----------:|---------:| |first_ary | 290.514k| 296.331k| | | -| 1.02x| |first_nonary | 166.954k| 169.178k| | | -| 1.01x| |first_noarg | 299.547k| 305.358k| | | -| 1.02x| |take3_ary | 129.388k| 188.360k| | | -| 1.46x| |take3_nonary | 90.684k| 112.688k| | | -| 1.24x| |take3_noarg | 131.940k| 189.471k| | | -| 1.44x| |chain-first_ary | 195.913k| 286.194k| | | -| 1.46x| |chain-first_nonary | 127.483k| 168.716k| | | -| 1.32x| |chain-first_noarg | 201.252k| 298.562k| | | -| 1.48x| |chain-take3_ary | 101.189k| 183.188k| | | -| 1.81x| |chain-take3_nonary | 75.381k| 112.301k| | | -| 1.49x| |chain-take3_noarg | 101.483k| 192.148k| | | -| 1.89x| |block | 296.696k| 292.877k| | | 1.01x| -|
This commit is contained in:
parent
6b3cff12f6
commit
54acb3dd52
Notes:
git
2020-07-23 17:53:30 +09:00
2 changed files with 55 additions and 42 deletions
22
benchmark/enum_lazy_zip.yml
Normal file
22
benchmark/enum_lazy_zip.yml
Normal file
|
@ -0,0 +1,22 @@
|
|||
prelude: |
|
||||
a = (1..3).lazy
|
||||
b = a.map {|x| x}
|
||||
|
||||
benchmark:
|
||||
first_ary: a.zip(["a", "b", "c"]).first
|
||||
first_nonary: a.zip("a".."c").first
|
||||
first_noarg: a.zip.first
|
||||
|
||||
take3_ary: a.zip(["a", "b", "c"]).take(3).force
|
||||
take3_nonary: a.zip("a".."c").take(3).force
|
||||
take3_noarg: a.zip.take(3).force
|
||||
|
||||
chain-first_ary: b.zip(["a", "b", "c"]).first
|
||||
chain-first_nonary: b.zip("a".."c").first
|
||||
chain-first_noarg: b.zip.first
|
||||
|
||||
chain-take3_ary: b.zip(["a", "b", "c"]).take(3).force
|
||||
chain-take3_nonary: b.zip("a".."c").take(3).force
|
||||
chain-take3_noarg: b.zip.take(3).force
|
||||
|
||||
block: a.zip("a".."c") {|x, y| [x, y]}
|
75
enumerator.c
75
enumerator.c
|
@ -1553,17 +1553,7 @@ lazyenum_size(VALUE self, VALUE args, VALUE eobj)
|
|||
return enum_size(self);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
lazy_size(VALUE self)
|
||||
{
|
||||
return enum_size(rb_ivar_get(self, id_receiver));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
lazy_receiver_size(VALUE generator, VALUE args, VALUE lazy)
|
||||
{
|
||||
return lazy_size(lazy);
|
||||
}
|
||||
#define lazy_receiver_size lazy_map_size
|
||||
|
||||
static VALUE
|
||||
lazy_init_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(val, m))
|
||||
|
@ -1840,6 +1830,7 @@ lazy_set_args(VALUE lazy, VALUE args)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static VALUE
|
||||
lazy_set_method(VALUE lazy, VALUE args, rb_enumerator_size_func *size_fn)
|
||||
{
|
||||
|
@ -1848,6 +1839,7 @@ lazy_set_method(VALUE lazy, VALUE args, rb_enumerator_size_func *size_fn)
|
|||
e->size_fn = size_fn;
|
||||
return lazy;
|
||||
}
|
||||
#endif
|
||||
|
||||
static VALUE
|
||||
lazy_add_method(VALUE obj, int argc, VALUE *argv, VALUE args, VALUE memo,
|
||||
|
@ -2342,58 +2334,59 @@ next_stopped(VALUE obj, VALUE _)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
lazy_zip_arrays_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, arrays))
|
||||
static struct MEMO *
|
||||
lazy_zip_arrays_func(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
|
||||
{
|
||||
VALUE yielder, ary, memo;
|
||||
long i, count;
|
||||
|
||||
yielder = argv[0];
|
||||
memo = rb_attr_get(yielder, id_memo);
|
||||
count = NIL_P(memo) ? 0 : NUM2LONG(memo);
|
||||
struct proc_entry *entry = proc_entry_ptr(proc_entry);
|
||||
VALUE ary, arrays = entry->memo;
|
||||
VALUE memo = rb_ary_entry(memos, memo_index);
|
||||
long i, count = NIL_P(memo) ? 0 : NUM2LONG(memo);
|
||||
|
||||
ary = rb_ary_new2(RARRAY_LEN(arrays) + 1);
|
||||
rb_ary_push(ary, argv[1]);
|
||||
rb_ary_push(ary, result->memo_value);
|
||||
for (i = 0; i < RARRAY_LEN(arrays); i++) {
|
||||
rb_ary_push(ary, rb_ary_entry(RARRAY_AREF(arrays, i), count));
|
||||
}
|
||||
rb_funcall(yielder, idLTLT, 1, ary);
|
||||
rb_ivar_set(yielder, id_memo, LONG2NUM(++count));
|
||||
return Qnil;
|
||||
LAZY_MEMO_SET_VALUE(result, ary);
|
||||
LAZY_MEMO_SET_PACKED(result);
|
||||
rb_ary_store(memos, memo_index, LONG2NUM(++count));
|
||||
return result;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
lazy_zip_func(RB_BLOCK_CALL_FUNC_ARGLIST(val, zip_args))
|
||||
static struct MEMO *
|
||||
lazy_zip_func(VALUE proc_entry, struct MEMO *result, VALUE memos, long memo_index)
|
||||
{
|
||||
VALUE yielder, ary, arg, v;
|
||||
struct proc_entry *entry = proc_entry_ptr(proc_entry);
|
||||
VALUE arg = rb_ary_entry(memos, memo_index);
|
||||
VALUE zip_args = entry->memo;
|
||||
VALUE ary, v;
|
||||
long i;
|
||||
|
||||
yielder = argv[0];
|
||||
arg = rb_attr_get(yielder, id_memo);
|
||||
if (NIL_P(arg)) {
|
||||
arg = rb_ary_new2(RARRAY_LEN(zip_args));
|
||||
for (i = 0; i < RARRAY_LEN(zip_args); i++) {
|
||||
rb_ary_push(arg, rb_funcall(RARRAY_AREF(zip_args, i), id_to_enum, 0));
|
||||
}
|
||||
rb_ivar_set(yielder, id_memo, arg);
|
||||
rb_ary_store(memos, memo_index, arg);
|
||||
}
|
||||
|
||||
ary = rb_ary_new2(RARRAY_LEN(arg) + 1);
|
||||
v = Qnil;
|
||||
if (--argc > 0) {
|
||||
++argv;
|
||||
v = argc > 1 ? rb_ary_new_from_values(argc, argv) : *argv;
|
||||
}
|
||||
rb_ary_push(ary, v);
|
||||
rb_ary_push(ary, result->memo_value);
|
||||
for (i = 0; i < RARRAY_LEN(arg); i++) {
|
||||
v = rb_rescue2(call_next, RARRAY_AREF(arg, i), next_stopped, 0,
|
||||
rb_eStopIteration, (VALUE)0);
|
||||
rb_ary_push(ary, v);
|
||||
}
|
||||
rb_funcall(yielder, idLTLT, 1, ary);
|
||||
return Qnil;
|
||||
LAZY_MEMO_SET_VALUE(result, ary);
|
||||
LAZY_MEMO_SET_PACKED(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static const lazyenum_funcs lazy_zip_funcs[] = {
|
||||
{lazy_zip_func, lazy_receiver_size,},
|
||||
{lazy_zip_arrays_func, lazy_receiver_size,},
|
||||
};
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* lazy.zip(arg, ...) -> lazy_enumerator
|
||||
|
@ -2407,7 +2400,7 @@ lazy_zip(int argc, VALUE *argv, VALUE obj)
|
|||
{
|
||||
VALUE ary, v;
|
||||
long i;
|
||||
rb_block_call_func *func = lazy_zip_arrays_func;
|
||||
const lazyenum_funcs *funcs = &lazy_zip_funcs[1];
|
||||
|
||||
if (rb_block_given_p()) {
|
||||
return rb_call_super(argc, argv);
|
||||
|
@ -2424,15 +2417,13 @@ lazy_zip(int argc, VALUE *argv, VALUE obj)
|
|||
}
|
||||
}
|
||||
ary = rb_ary_new4(argc, argv);
|
||||
func = lazy_zip_func;
|
||||
funcs = &lazy_zip_funcs[0];
|
||||
break;
|
||||
}
|
||||
rb_ary_push(ary, v);
|
||||
}
|
||||
|
||||
return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
|
||||
func, ary),
|
||||
ary, lazy_receiver_size);
|
||||
return lazy_add_method(obj, 0, 0, ary, ary, funcs);
|
||||
}
|
||||
|
||||
static struct MEMO *
|
||||
|
|
Loading…
Reference in a new issue