Sven Johansson <sven_u_johansson / spray.se> wrote:

<snip/>

> One last question, then - while the style above is easily more
> readable and quite... enjoyable, for lack of a better word, to read,
> how does Ruby measure up when it comes to passing all those variables
> around to functions (method calls) all the time? Do I lose significant
> performance by having method calls in inner loops? And no, I can hear
> it already; "Dude, you traverse big directories, do calculations on a
> big number of big files and push the filesystem to it's limits copying
> them like there was no tomorrow already..." Obviously, it doesn't
> matter here. But would it matter if one was wrtiting, say, a port
> listener or some other reasonably performance critical application?

There are two ways to answer this: reasoning and testing.  You'll get the 
definitive answer only by measuring performance of a real application.  On 
the theoretical side we can state this: first, Ruby uses call by value but 
values are object references (i.e. objects are not copied as they are with 
call by value in C++ and there are two references so assignment does not 
affect the calling environment); this has rather low overhead compared to a 
real call by value where objects must be copied.  Second, every method call 
has a certain overhead attached to it (unless a runtime system as the Java 
VM inlines it at run time).

A simple test shows that there is indeed significant overhead attached to 
method invocations - if methods perform simple tasks.  The relative overhead 
of course depends on the work the method performs.  I for my part would 
always start with a modularized version and only inline methods if this is 
actually a cure for a performance problem.  There is a famous quote about 
premature optimization...

#! /usr/bin/env ruby

require 'benchmark'

REP = 1_000_000

def foo(n) 0 + n end

Benchmark.bmbm(10) do |bm|
  bm.report("direct") do
    REP.times { x = 0 + 1 }
  end

  bm.report("method") do
    REP.times { x = foo(1) }
  end
end


Rehearsal ---------------------------------------------
direct      1.188000   0.000000   1.188000 (  1.201000)
method      2.156000   0.000000   2.156000 (  2.166000)
------------------------------------ total: 3.344000sec

                user     system      total        real
direct      1.187000   0.000000   1.187000 (  1.217000)
method      2.172000   0.000000   2.172000 (  2.234000)

$ ruby -e 'puts 2.172000 / 1.187000'
1.82982308340354

Happy new year!

    robert