Ruby Ternary operator re-written with Boolean operators

Just noticed something interesting (well not that interesting). Ternary operators in Ruby can be re-written using Boolean operators e.g.

method = object.respond_to?(:foo) ? :foo : :bar

would become…

method = object.respond_to?(:foo) && :foo || :bar

Simply replace ? with && and : with ||
I don’t know if there is any performance gain here, anyone care to investigate?

7 thoughts on “Ruby Ternary operator re-written with Boolean operators”

  1. “I don’t know if there is any performance gain here, anyone care to investigate?”
    Not really. I’m not in the habit of obfuscating my code to take advantage of minor (it can’t be anything but) performance gains. Also, who’s to say the interpreter won’t change to make the alternate method faster in the future?

  2. Rik: Ohhh… touchy! It was only a simple observation.
    I wasn’t advocating a complete paradigm shift. Just wondered if anyone had come across it before and had noticed any performance gains.

  3. That’s a quite normal pattern in Python. There is one caveat to be aware of though, if you do “foo = a and b or c” you have to make sure b can’t evaluate to false (because then the expression will return c).

  4. You’re potentially performing two boolean operations too.
    During benchmarking of a simple string building algorithm, I ended up looking at some of the more minor performance areas, like the boolean operators and functions.
    Originally I ‘discovered’ that if/else was faster than the ternary operator; however, further testing revealed this had more to do with specific testing code than anything else.
    if true
    true
    else
    false
    end
    is slower than
    true ? true : false
    However, their logic are the same.
    Further testing (with the help of zenspider, probably more to his annoyance than anything else), I realised that:
    if true then true else false end
    is effectively the same speed as the ternary operator.
    Interesting? Maybe.
    Using ‘return’ instead of implicit return values I also found to be slower.
    On that note, you can also do this (which clearly isn’t faster, it’s just interesting) (from #ruby-lang):
    # 02:38 flgr: interestingly, Array#empty? can be implemented as ary.inject(true) { false }
    # 02:39 flgr: what this means is that you can replace ary.empty?() ? a : b with ary.inject(a){ b } all the time
    # 02:50 flgr: raggi: you can probably make it faster by using { break b } ๐Ÿ™‚
    N.B. that break, like return, is slightly slower than not doing so, using the tests that I built some time ago, which may need to be re-done.
    Analysis of speed at this level is extremely difficult from within the language, and is massively sensitive to environmental influence. It’s almost easier to look at the source and rely on that.

  5. sidenote: the first example of the if/else block should have newlines, the latter should not.
    Apologies for the complete lack of formatting.

  6. raggi: Thanks, interesting stuff. I suppose it all comes down to boolean comparisons at the end of the day and the more operations needed the slower things will be (same with SQL queries).
    Also speed depends on whether the value before the operator evaluates to true i.e. true || false would be faster than false || true as in the first example, the second value does not need checking but it does in the latter.
    The inject for empty? is interesting, inject always makes my brain ache even though I’ve been using it for years.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.