Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"if" without "else" much slower than "if" with empty "else" #6025

Closed
p6rt opened this issue Jan 21, 2017 · 5 comments
Closed

"if" without "else" much slower than "if" with empty "else" #6025

p6rt opened this issue Jan 21, 2017 · 5 comments
Labels
LTA Less Than Awesome; typically an error message that could be better optimizer

Comments

@p6rt
Copy link

p6rt commented Jan 21, 2017

Migrated from rt.perl.org#130613 (status was 'resolved')

Searchable as RT130613$

@p6rt
Copy link
Author

p6rt commented Jan 21, 2017

From alex6k@yahoo.com

Take a look at the following examples - the second is more than 10x(!!!) faster​:
m​: my int $i = 0; loop { if $i++ == 10_000_000 { last }}; say now - INIT now;rakudo-moar f97d5c​: OUTPUT«2.0606382␤»
m​: my int $i = 0; loop { if $i++ == 10_000_000 { last } else {} }; say now - INIT now;
rakudo-moar f97d5c​: OUTPUT«0.1727145␤»

In my understanding of https://github.com/rakudo/rakudo/blob/nom/src/Perl6/Actions.nqp#L1675 the first example is equivalent to​:

m​: my int $i = 0; loop { if $i++ == 10_000_000 { last } else { Empty } }; say now - INIT now;
rakudo-moar f97d5c​: OUTPUT«WARNINGS for <tmp>​:␤Useless use of constant value Empty in sink context (line 1)␤2.120407471␤»

@p6rt
Copy link
Author

p6rt commented Jan 21, 2017

From @zoffixznet

On Sat, 21 Jan 2017 11​:45​:10 -0800, alex6k@​yahoo.com wrote​:

Take a look at the following examples - the second is more than
10x(!!!) faster​:
m​: my int $i = 0; loop { if $i++ == 10_000_000 { last }}; say now -
INIT now;rakudo-moar f97d5c​: OUTPUT«2.0606382␤»
m​: my int $i = 0; loop { if $i++ == 10_000_000 { last } else {} }; say
now - INIT now;
rakudo-moar f97d5c​: OUTPUT«0.1727145␤»

In my understanding of
https://github.com/rakudo/rakudo/blob/nom/src/Perl6/Actions.nqp#L1675
the first example is equivalent to​:

m​: my int $i = 0; loop { if $i++ == 10_000_000 { last } else { Empty }
}; say now - INIT now;
rakudo-moar f97d5c​: OUTPUT«WARNINGS for <tmp>​:␤Useless use of constant
value Empty in sink context (line 1)␤2.120407471␤»

That's because the two examples you are comparing are entirely different. The case with implicit or explicit Empty can
be used in lists, in which the Empty slips away​:

  <Zoffix> m​: sub stuff { if 0 {} }; dd [1, stuff(), 4]
  <camelia> rakudo-moar 7f245f​: OUTPUT«[1, 4]␤»

But the explicit `else {}` results in a Nil, which leaves unwanted stuff in lists​:

  <Zoffix> m​: sub stuff { if 0 {} else {} }; dd [1, stuff(), 4]
  <camelia> rakudo-moar 7f245f​: OUTPUT«[1, Any, 4]␤»


So naturally, the optimizer can check whether whether the value of the conditional is ever used and avoid the Empty stuff, and it does so in some cases​:

  <Zoffix> m​: sub stuff { if 0 {} else {}; 42 }; for ^100_000 { $ = [1, stuff(), 4] }; say now - INIT now;
  <camelia> rakudo-moar 7f245f​: OUTPUT«0.306001␤»
  <Zoffix> m​: sub stuff { if 0 {}; 42 }; for ^100_000 { $ = [1, stuff(), 4] }; say now - INIT now;
  <camelia> rakudo-moar 7f245f​: OUTPUT«0.3428267␤»

It doesn't seem to do that for the OP case (even when you tack on an extra value after it so result isn't used). So perhaps it could be taught to do so. Note that I doubt you'd see much speedup from this in real-life code​: "10 times" may sound impressive, but the average comes down to difference between 21.9 *nano*seconds vs 219 *nano*seconds.

@p6rt
Copy link
Author

p6rt commented Jan 21, 2017

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Dec 30, 2017

From @zoffixznet

On Sat, 21 Jan 2017 11​:45​:10 -0800, alex6k@​yahoo.com wrote​:

Take a look at the following examples - the second is more than
10x(!!!) faster​:
m​: my int $i = 0; loop { if $i++ == 10_000_000 { last }}; say now -
INIT now;rakudo-moar f97d5c​: OUTPUT«2.0606382␤»
m​: my int $i = 0; loop { if $i++ == 10_000_000 { last } else {} }; say
now - INIT now;
rakudo-moar f97d5c​: OUTPUT«0.1727145␤»

In my understanding of
https://github.com/rakudo/rakudo/blob/nom/src/Perl6/Actions.nqp#L1675
the first example is equivalent to​:

m​: my int $i = 0; loop { if $i++ == 10_000_000 { last } else { Empty }
}; say now - INIT now;
rakudo-moar f97d5c​: OUTPUT«WARNINGS for <tmp>​:␤Useless use of constant
value Empty in sink context (line 1)␤2.120407471␤»

Thank you for the report. This is now fixed. The `else`-less version is now nearly twice faster​:

  $ ./perl6 -e 'm​: my int $i = 0; loop { if $i++ == 10_000_000 { last }}; say now - INIT now;'
  0.09784453
  $ ./perl6 -e 'm​: my int $i = 0; loop { if $i++ == 10_000_000 { last } else {} }; say now - INIT now;'
  0.1641829

Fix​: rakudo/rakudo@1815c36843ac58f
Closing without tests, since AFAIK we haven't figured out how to cover perf issues well yet.

@p6rt
Copy link
Author

p6rt commented Dec 30, 2017

@zoffixznet - Status changed from 'open' to 'resolved'

@p6rt p6rt closed this as completed Dec 30, 2017
@p6rt p6rt added LTA Less Than Awesome; typically an error message that could be better optimizer labels Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LTA Less Than Awesome; typically an error message that could be better optimizer
Projects
None yet
Development

No branches or pull requests

1 participant