On Return

Posted by tobi — 11:49 AM Apr 03

ActiveSupport has this really nice returning tool. It allows you to rewrite the common pattern of initialization and returning a object from am method like this:

returning something = Thing.new do
  something.this
  something.that
end

We were wondering if there may be a performance issue with the tool so a quick benchmark showed the following:

                                          user     system      total        real
def n; i = 0; return i; end           0.510000   0.000000   0.510000 (  0.520417)
def n; i = 0; i ; end                 0.340000   0.000000   0.340000 (  0.344569)
def n; returning i = 0 do; end; end   0.730000   0.000000   0.730000 (  0.726853)

Those numbers are after 1m runs on a core 2 duo laptop. As you can see the difference is very minor. Code vanity can safely prevail. Full Benchmark

Comments

  • Pete Forde 03 Apr 12:38

    I had no idea that returning existed! Thanks for the tip.

    My question is why specifying return i is 40% slower?

  • Hongli Lai 03 Apr 13:00

    Pete: It’s because of function call overhead. There’s nothing that can be done about that (except making it a full language construct, but that’s overkill).

  • Jay Fields 03 Apr 14:12

    I’ve never seen returning used that way, I always use.

    returning Thing.new do |thing| thing.this thing.that end

    I guess it works either way.

  • tobias Lütke 03 Apr 15:33

    Jay: Block variable or no block doesn’t seem to impact performance.

    I personally think that the example in the post looks more natural, more like build in syntax but that’s definitely a taste thing.

  • rick 03 Apr 15:54

    Ruby 1.9 has tap.

    Thing.new.tap { |t| t.this }

    Of course, some objects like ActiveRecord models already take a block:

    Thing.new { |t| t.this = that }

  • Zbo 03 Apr 17:12

    2x slower is a minor difference?

  • Neeraj 03 Apr 22:05

    I couldn’t find returning declared in ActiveSupport. Does anyone have a link to it?

    I thought returning was a creature of “facets”. http://facets.rubyforge.org/quick/rdoc/core/classes/Kernel.html#M000374

  • Sb 04 Apr 05:48

    Zbo, agreed! How is 100% slower a “very minor” performance hit?

  • tobi 06 Apr 01:43

    100% in an application which does nothing but return data. Even in the simplest of apps this would be totally negligible. Notice that this was 1m invocations performed in sub second.

Commenting are now closed…