Issue #14908 has been updated by shyouhei (Shyouhei Urabe). No objection. I guess @nobu is trying to fix it. ---------------------------------------- Bug #14908: Enumerator::Lazy creates unnecessary Array objects. https://bugs.ruby-lang.org/issues/14908#change-74080 * Author: chopraanmol1 (Anmol Chopra) * Status: Open * Priority: Normal * Assignee: * Target version: * ruby -v: ruby 2.6.0dev (2018-07-11 trunk 63949) [x86_64-linux] * Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN ---------------------------------------- Benchmark result on trunk: ~~~ user system total real Lazy: 0.120000 0.000000 0.120000 ( 0.119958) Normal: 0.056000 0.004000 0.060000 ( 0.062848) 2.142857 0.000000 NaN ( 1.908698) ++++++++++++++++++++++++++++++++++++++++++++++++++ Lazy: Total allocated: 122240 bytes (3033 objects) Total retained: 0 bytes (0 objects) allocated memory by class -------------------------------------------------- 120480 Array 880 Proc 384 Enumerator::Lazy 264 Object 168 Enumerator::Generator 64 Enumerator::Yielder allocated objects by class -------------------------------------------------- 3012 Array 11 Proc 3 Enumerator::Generator 3 Enumerator::Lazy 3 Object 1 Enumerator::Yielder ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ Normal: Total allocated: 72120 bytes (3 objects) Total retained: 0 bytes (0 objects) allocated memory by class -------------------------------------------------- 72120 Array allocated objects by class -------------------------------------------------- 3 Array ++++++++++++++++++++++++++++++++++++++++++++++++++ ~~~ As you may observe an extra array is created for every final element. Enumerator::Yielder#yield method has arity of -1 which wrap every elements in array. The same goes for Enumerator::Yielder#<< method, I'm proposing to change arity for Enumerator::Yielder#<< to 1 from -1 and use it internally for the lazy enum. It will also make << method definition consistent with other classes(Array, String & etc). I've applied the following set of changes: **https://github.com/ruby/ruby/pull/1912** which result in the following: ~~~ user system total real Lazy: 0.108000 0.000000 0.108000 ( 0.108484) Normal: 0.052000 0.008000 0.060000 ( 0.062528) 2.076923 0.000000 NaN ( 1.734961) ++++++++++++++++++++++++++++++++++++++++++++++++++ Lazy: Total allocated: 2240 bytes (33 objects) Total retained: 0 bytes (0 objects) allocated memory by class -------------------------------------------------- 880 Proc 480 Array 384 Enumerator::Lazy 264 Object 168 Enumerator::Generator 64 Enumerator::Yielder allocated objects by class -------------------------------------------------- 12 Array 11 Proc 3 Enumerator::Generator 3 Enumerator::Lazy 3 Object 1 Enumerator::Yielder ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ Normal: Total allocated: 72120 bytes (3 objects) Total retained: 0 bytes (0 objects) allocated memory by class -------------------------------------------------- 72120 Array allocated objects by class -------------------------------------------------- 3 Array ++++++++++++++++++++++++++++++++++++++++++++++++++ ~~~ This changes reduces the memory utilization and also by a tiny fraction improves performance for the lazy enumerator ---Files-------------------------------- lazy_test.rb (1.26 KB) -- https://bugs.ruby-lang.org/ Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>