Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Re^2: new way to code html?

by tobyink (Abbot)
on Nov 21, 2012 at 07:05 UTC ( #1004854=note: print w/replies, xml ) Need Help??

in reply to Re: new way to code html?
in thread new way to code html?

Using the ternary operator (?:) over if/else can sometimes be a useful optimisation. Especially if it's in a deeply nested loop that gets executed thousands of times.

On my machine, ternary is consistently about 25% faster.

use Benchmark ':all'; my ($foo, $bar); cmpthese(-1, { ternary => sub { int(rand(2)) ? ( $foo = 1 ) : ( $bar = 1 ) + }, if_else => sub { if(int(rand(2))) { $foo = 1 } else { $bar = 1 } + }, });

Why is this? It's because the braces used in if/else structures introduce a new lexical scope, so when they're encountered Perl needs to create a new pad (i.e. a structure where it keeps my variables) even if that pad doesn't get used.

Of course, generally speaking clarity should win over speed. But in subs which are executed many thousands of times, use of the ternary for simple conditionals is a handy trick to have up your sleeve.

See also: the block forms of map and grep; control structures versus statement modifiers.

Update: thanks anonymous monk below for pointing out the precedence error in my original code for the ternary sub. Corrected above now. I think this illustrates perfectly my statement that "generally speaking clarity should win over speed". :-)

perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Replies are listed 'Best First'.
Re^3: new way to code html?
by Anonymous Monk on Nov 21, 2012 at 08:23 UTC

    use of the ternary for simple conditionals is a handy trick to have up your sleeve.

    I'd worry about having a grasp of the language (context, syntax) before worrying about micro-optimizations

    -MO=Deparse,-p says

    use Benchmark (':all'); my($foo, $bar); cmpthese((-1), {'ternary', sub { ((int(rand(2)) ? ($foo = 1) : $bar) = 1); } , 'if_else', sub { if (int(rand(2))) { ($foo = 1); } else { ($bar = 1); } } });

    More clearly  ((int(rand(2)) ? ($foo = 1) : $bar) = 1);


    ( ( int(rand(2)) ? ($foo = 1) : $bar ) = 1 );
    which is an error

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1004854]
[perldigious]: but... but... perldigious is the unvirtuous kind of lazy in this case. :-)
[perldigious]: Just kidding. Thanks 1nickt, I'll go ahead and do it the right way. An extra set of brackets and a little extra indentation isn't too much to ask.
[karlgoethebier]: perldigious: perhaps a block if you are paranoid ;-)
[choroba]: but undef %hash and %hash = () both work, too, but the first one keeps the memory allocated, while the latter makes it available for other parts of the program.
[choroba]: iirc
[perldigious]: karlgoethebier: Well it is a pretty old and complicated (for me) bit of code I wrote (poorly by my current standards), so I'm expecting everything to break when I add the scoping and find out what else is undesireably scope changed. :-)
[perldigious]: Ah, thanks choroba, that sort of thing was precisely what I was wondering when I asked.

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (8)
As of 2017-07-21 19:51 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (335 votes). Check out past polls.