Re: Sheer idle curiousity . . .
by BrowserUk (Patriarch) on Oct 23, 2013 at 22:14 UTC
|
why would using abs be so much faster
Because it requires less opcodes.
- With the ternary, it has to:
- load the value;
- load the constant;
- perform the compare;
- perform an assignment in both branches.
- With the unless $x >= 0 (your condition is wrong), it has to
- load the value;
- load the constant;
- perform the compare;
- perform an assignment in one branch.
- With the unless abs $x the is no constant to load; and abs is just an opcode the same as greater than or less than:
- load the abs value;
- perform the compare;
- perform an assignment in one branch.
Best shown by the difference in the Concise output, where each successively faster option requires one less opcode than the precedent:
C:\test>perl -MO=Concise -E"my$x=-1; $x = $x<0?0:$x;"
e <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 46 -e:1) v:%,{ ->3
5 <2> sassign vKS/2 ->6
3 <$> const[IV -1] s ->4
4 <0> padsv[$x:46,47] sRM*/LVINTRO ->5
6 <;> nextstate(main 47 -e:1) v:%,{ ->7
d <2> sassign vKS/2 ->e
- <1> null sK/1 ->c
a <|> cond_expr(other->b) sK/1 ->f
9 <2> lt sK/2 ->a
7 <0> padsv[$x:46,47] s ->8
8 <$> const[IV 0] s ->9
b <$> const[IV 0] s ->c
f <0> padsv[$x:46,47] s ->c
c <0> padsv[$x:46,47] sRM* ->d
-e syntax OK
C:\test>perl -MO=Concise -E"my$x=-1; $x = 0 unless $x >=0;"
e <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 46 -e:1) v:%,{ ->3
5 <2> sassign vKS/2 ->6
3 <$> const[IV -1] s ->4
4 <0> padsv[$x:46,47] sRM*/LVINTRO ->5
6 <;> nextstate(main 47 -e:1) v:%,{ ->7
- <1> null vK/1 ->e
a <|> or(other->b) vK/1 ->e
9 <2> ge sK/2 ->a
7 <0> padsv[$x:46,47] s ->8
8 <$> const[IV 0] s ->9
d <2> sassign vKS/2 ->e
b <$> const[IV 0] s ->c
c <0> padsv[$x:46,47] sRM* ->d
-e syntax OK
C:\test>perl -MO=Concise -E"my$x=-1; $x = 0 unless abs($x);"
d <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 46 -e:1) v:%,{ ->3
5 <2> sassign vKS/2 ->6
3 <$> const[IV -1] s ->4
4 <0> padsv[$x:46,47] sRM*/LVINTRO ->5
6 <;> nextstate(main 47 -e:1) v:%,{ ->7
- <1> null vK/1 ->d
9 <|> or(other->a) vK/1 ->d
8 <1> abs[t3] sK/1 ->9
7 <0> padsv[$x:46,47] s ->8
c <2> sassign vKS/2 ->d
a <$> const[IV 0] s ->b
b <0> padsv[$x:46,47] sRM* ->c
-e syntax OK
Of course, speed is no good to you if it doesn't perform the required function ... (davido++)
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
|
|
Thanks that really is clear - appreciated.
| [reply] |
Re: Sheer idle curiousity . . .
by davido (Cardinal) on Oct 23, 2013 at 21:45 UTC
|
What does your intuition tell you this code does?
d=>sub{
$wait = 0 unless abs($wait);
$wait = -34;
},
In particular, abs returns the absolute value. The absolute value of -34 is 34, which is "true". Since your condition is never false, you never fall through to the action of the "unless" clause.
| [reply] [d/l] |
|
|
d=>sub{
$wait = 0 unless ($wait == abs($wait));
$wait = -34;
},
I thought the results had shot up on my home pc.
Rate d c b a
d 3468819/s -- -8% -10% -13%
c 3780923/s 9% -- -1% -5%
b 3834916/s 11% 1% -- -4%
a 3997317/s 15% 6% 4% --
and
Rate d c b a
d 3246175/s -- -8% -15% -17%
c 3526456/s 9% -- -7% -9%
b 3799184/s 17% 8% -- -2%
a 3890565/s 20% 10% 2% --
It's still the outright winner - so the questions still stand.
| [reply] [d/l] [select] |
|
|
| [reply] |
|
|
| [reply] |
|
|
|
|
Re: Sheer idle curiousity . . .
by Anonymous Monk on Oct 24, 2013 at 02:48 UTC
|
e=>sub{
$wait *= $wait > 0;
$wait = -34;
},
For negative numbers:
Rate d b a c e
d 7216838/s -- -7% -13% -16% -35%
b 7785170/s 8% -- -6% -10% -30%
a 8270205/s 15% 6% -- -4% -26%
c 8609980/s 19% 11% 4% -- -23%
e 11128061/s 54% 43% 35% 29% --
For positive numbers:
Rate a d e c b
a 9665991/s -- -10% -14% -24% -26%
d 10777285/s 11% -- -4% -15% -17%
e 11190507/s 16% 4% -- -12% -14%
c 12748698/s 32% 18% 14% -- -2%
b 13022958/s 35% 21% 16% 2% --
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] |
Re: Sheer idle curiousity . . .
by vsespb (Chaplain) on Oct 23, 2013 at 23:01 UTC
|
$wait = 0 unless abs($wait);
unlike other examples, never assigns anything to $wait if $wait is -34.
Proof:
my $wait = -34;
$wait = 0 unless abs($wait);
print $wait;
prints -34
So if you change your benchmark to
$wait = 0 if abs($wait);
you'll see, difference is small (I got 4%). (even through abs() is still used).
UPD:Oh, @TheMonkWithoutVows and you(OP) are same persons :)
| [reply] [d/l] [select] |
Re: Sheer idle curiousity . . .
by hdb (Monsignor) on Oct 24, 2013 at 07:27 UTC
|
Running a comparison of a, c and e several times on Win 7, Strawberry 5.16 shows the following results:
Rate e a c
e 7079226/s -- -1% -3%
a 7185758/s 2% -- -1%
c 7269278/s 3% 1% --
Rate e c a
e 7072032/s -- -1% -3%
c 7143388/s 1% -- -2%
a 7316126/s 3% 2% --
Rate c e a
c 7161561/s -- -1% -4%
e 7257544/s 1% -- -2%
a 7427981/s 4% 2% --
so my conclusion would be that the difference between the three is negligible. This is with -34 as the test number. For +34 the picture is quite different:
Rate e a c
e 6807195/s -- -26% -37%
a 9201425/s 35% -- -15%
c 10867659/s 60% 18% --
where c is a clear and consistent winner.
What shall I make of this in the light of the thread above?
| [reply] [d/l] [select] |
|
|
# This is perl, v5.10.1 (*) built for i486-linux-gnu-thread-multi
# negative
Rate d c e a b
d 1219274/s -- -7% -15% -20% -31%
c 1315339/s 8% -- -9% -13% -26%
e 1441482/s 18% 10% -- -5% -19%
a 1519028/s 25% 15% 5% -- -15%
b 1778883/s 46% 35% 23% 17% --
# positive
Rate d e c a b
d 1300194/s -- -3% -6% -13% -13%
e 1336169/s 3% -- -3% -10% -10%
c 1375954/s 6% 3% -- -7% -8%
a 1486080/s 14% 11% 8% -- -0%
b 1492276/s 15% 12% 8% 0% --
The winner here is, quite unexpectedly, B.
Another cpu, also on Perl 5.10.1 but amd64, says B is 80% faster than the worst contender (E) when negative; and A is 51% faster than E (B having the second place at 42% faster) when positive.
Third cpu with Perl 5.14.4 gives a negligible win for E -- D being the low anchor. So I think we can conclude that the Perl version matters the most? | [reply] [d/l] |
Re: Sheer idle curiousity . . .
by AnomalousMonk (Archbishop) on Oct 24, 2013 at 03:50 UTC
|
And you and your cow-orkers spent how much time on this today?!? I wish I worked where you work. (Actually, I foresee there may be a couple of openings RSN...:)
| [reply] |
|
|
| [reply] |
|
|
I work at The Unemployment Line. You don't want to work here. There are plenty of openings.
| [reply] |
Re: Sheer idle curiousity . . .
by ikegami (Patriarch) on Oct 25, 2013 at 14:50 UTC
|
To put it into perspective, the slowest one of the above takes 180 billionths of a second, while a subroutine call with a single ten-character string argument takes 650 billionths of a second.
If your tenth of millionths of seconds are that precious, you should probably inline your subs.
'$wait = 0 unless ($wait == abs($wait)); $wait = 34;'
'sub { my ($x) = @_; }->(q{abcdefghij})'
| [reply] [d/l] |