Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I have comparing Benchmarks using if-else blocks and the tertiary condition and found the tertiary to be twice as fast. Why is;
( $var ? print 'yes' : print 'no' )
Twice as fast as;
if ( $var ) { print 'yesy'; } else { print 'no'; }
Also is there a perldoc that discusses this? Thanks,

Replies are listed 'Best First'.
Re: if-else vs. tertiary effieciency?
by fruiture (Curate) on Sep 14, 2002 at 14:52 UTC

    First of all, i'd write:

    print $var ? 'yes' : 'no'

    btw. it's a 'ternary' operator. I cannot agree with your results, my perl (5.6.1 and 5.8.0) lets ?: be only about 13% faster:

    use Benchmark qw/cmpthese/; our @values = (1,0,undef,50,'yes','no','0E0',0e0,0); my $subs = { ifelse => sub {foreach(@values){ my $x; if($_){$x = 'yes'} else {$x = 'no'} }}, trinary => sub {foreach(@values){ my $x; $x = $_ ? 'yes' : 'no' }}, }; $_->() for values %$subs; cmpthese( $ARGV[0] => $subs );

    And to finally (not) answer your question: The ?: operator is much "lighter" than if-else, it is one expression without scope, whereas the if-block can have it's own lexicals. If you wanted to have the functionaltiy of if-else in a ?: construct, you'd have to use do BLOCK, which already slows down the whole thing...

    UPDATE: Aristotle is of course right about the "ternary" operator.

    --
    http://fruiture.de
      btw. it's a 'trinary' operator.
      If you correct someone's vocabulary, please do it right. :-) The term is ternary.

      Makeshifts last the longest.

        Actually, either "Ternary" or "Trinary" is acceptable.

        --MrNobo1024
        s]]HrLfbfe|EbBibmv]e|s}w}ciZx^RYhL}e^print

        I'm sinking into the ground... thanks (must have come from the german "trinär")

        --
        http://fruiture.de
      First of all, i'd write:print $var ? 'yes' : 'no' wouldnt this print yes or no depending on $var...it looks like the Anonymous Monk wants to print yes or no depending on whether $var has a value or not
      $var ? print 'yes' : print 'no'
      seems right to me, am i missing something?

      Update: I just started learning how ?: works, so i just wanted to know why
      print $var ? 'yes' : 'no'
      will also work, i guess im not understanding how it evaluates $var...the way im reading ?: is if 1st arg (print $var) then second (yes) else third(no) so how does it know that you actually want to print yes or no? with the way im looking at it, it is
      if(print $var){ 'yes' }else{ 'no' }
      anyone care to explain to me, id appreciate it greatly
        Think of it as:
        print ( $boolean ? $true_value : $false_value );
        or in your terms:
        print ( if($var}{ 'yes' }else{ 'no' } );
        I like this less because it is pseudo-code that looks
        much like code. So it seems to imply many things that
        aren't true. The conditional operator is only an
        operator not a statement.
Re: if-else vs. tertiary effieciency?
by theorbtwo (Prior) on Sep 15, 2002 at 15:02 UTC

    Oh, one thing I meant to say earlier, but forgot about: the if statement and the ?: operator aren't really the seperate beasts they appear to be. See the documentation of B::Deparse, and the section on -q, specificly.

    perl -MO=Deparse,-p,-x9 -e "if ($/) {print 1} else {print 2}" ($/ ? do { print(1) } : do { print(2) }); -e syntax OK perl -MO=Deparse,-p,-x9 -e "$/?print 1:print 2" ($/ ? print(1) : print(2)); -e syntax OK

    All the speed diference you see is from those do{}s. Moral of the story? Perl is even stranger then it looks, it has a poor optimizer, do{} is expensive, and other. Pick any combination you feel like.


    Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).