From: Sylvain Joyeux Date: 2008-09-22T22:49:21+09:00 Subject: Re: for or each? On Mon, Sep 22, 2008 at 07:42:24PM +0900, Brian Candler wrote: > Sylvain Joyeux wrote: > > Nope. each { } needs one new scope for each iteration > > By 'scope' do you mean 'stack frame'? > creates three objects which need to be garbage-collected, and therefore > that the loop > > for i in (1..3) > foo(i) > end > > also creates three garbage objects. Yes. Except that collection.each do |obj| foo(obj) end creates twice the amount of for obj in collection foo(obj) end which is what we are trying to compare here. > I don't believe that's the case. I would imagine that the stack runs as, > well, a stack. (It's not quite that simple when you get into creating > closures of course, but if you call a closure 1000 times, you're not > creating 1000 new closures) > > Am I missing something? Yes. I don't know for the current version of the 1.9 VM, but currently the interpreter does not 'reuse' stack frames, and therefore you *do* create one object per new scope. To cut down the discussion, ObjectSpace#each_object does *not* give you those, so you can't count them with it. > Finally, I tried some simple measurements. > > $ time ruby -e 'a = (1..5_000_000).to_a; a.each { :dummy }' > $ time ruby -e 'a = (1..5_000_000).to_a; for i in a; :dummy; end' > > Under ruby 1.8.6p114, I find the first is about 5% faster. > > Under ruby 1.8.4 (Ubuntu Dapper), I find the first is about 25% faster. Interesting. I have the same results, but (on my machine) the following is even slower: $ time ruby -e 'a = (1..5_000_000).to_a; a.each { |i| :dummy }'