From: James Gray Date: 2008-01-04T23:22:19+09:00 Subject: Re: Enumerable#zip Needs Love On Jan 4, 2008, at 12:11 AM, Martin Duerst wrote: > I think the two changes have to be looked at separately. Sounds good to me. I posted them here with the hope of inspiring discussion around them. Perhaps if enough of us reach agreement, Matz will take pity on us zip() fans. :) > At 07:05 08/01/04, James Gray wrote: >> The community has been building a Ruby 1.9 compatibility tip list on >> my blog. While most of the changes are good, a pattern is emerging: >> Enumerable#zip was damaged in the translation. The short story is: >> >> * Making Enumerable#zip() return and Enumerable::Enumerator when >> called without a block hid a very useful return value that was >> already >> in place. Now we typically need `enum.zip(...).to_a` to get the >> expected results. > > My recollection may be faulty, and I may not be the typical case, > but I usually have been using zip immediately followed by some > additional operation, which should still work in 1.9, rather > than to produce an explicit array. Well, Array is a superset of Enumerable, right? So the operations you can follow up with are increased by an Array return value and you don't lose access to any of the iterators. >> * Beyond being less attractive, Enumerable::Enumerator is quite a bit >> slower. It looks like `enum.zip(...).to_a` in 1.9 is about 12 times >> slower than a straight `enum.zip(...)` in Ruby 1.8. > > That looks bad. But have you looked at how much slower or > faster things get when zip is used not just to create an array? I hadn't before, no. Let's check though: $ ruby -v speed_test.rb ruby 1.8.6 (2007-09-24 patchlevel 111) [i686-darwin9.1.0] Rehearsal ------------------------------------------------- zip().to_a(): 8.040000 0.020000 8.060000 ( 8.066183) zip() { }: 8.770000 0.020000 8.790000 ( 8.789457) --------------------------------------- total: 16.850000sec user system total real zip().to_a(): 8.100000 0.010000 8.110000 ( 8.112016) zip() { }: 8.820000 0.010000 8.830000 ( 8.852391) $ ruby_dev -v speed_test.rb ruby 1.9.0 (2007-12-25 revision 14709) [i686-darwin9.1.0] Rehearsal ------------------------------------------------- zip().to_a(): 100.870000 9.620000 110.490000 (110.607631) zip() { }: 82.510000 9.410000 91.920000 ( 92.208807) -------------------------------------- total: 202.410000sec user system total real zip().to_a(): 99.890000 9.940000 109.830000 (109.915261) zip() { }: 81.550000 9.470000 91.020000 ( 90.950279) $ cat speed_test.rb #!/usr/bin/env ruby -wKU require "benchmark" DATA = Array.new(25) { rand } TESTS = 1_000_000 Benchmark.bmbm do |results| results.report("zip().to_a():") { TESTS.times { DATA.zip(DATA).to_a } } results.report("zip() { }:") { TESTS.times { DATA.zip(DATA) { } } } end __END__ Good call. It seems that zip() performance on the whole has tanked. James Edward Gray II