Along that same line of thinking, see if the data can be morphed outside of any tight
loops so that inside the loop, you can check for empty(), isset(), or === null. From what
I’ve read, those are a lot faster in PHP than comparing with an untyped variable.
From: Adam Wight <adam.wight(a)wikimedia.de>
Sent: August 2, 2021 4:55 AM
To: wikitech-l(a)lists.wikimedia.org
Subject: [Wikitech-l] Re: Goto for microoptimisation
On 7/31/21 6:09 AM, Tim Starling wrote:
Certain flow control patterns cannot be implemented
efficiently in PHP without using "goto". The current example in Gerrit
708880<https://gerrit.wikimedia.org/r/c/mediawiki/core/+/708880/5/includ…
comes down to:
If `goto` really does help, please go to it with no objections from me!
But could you split the guard logic in your example, like this? The `||` operator will
short-circuit away the expensive test for "is 2" in the case of "is
1".
$state_1 = ($x == 1);
$state_2 = !($state_1 || $x != 2);
if ( $state_1 ) {
action1();
} else {
action_not_1();
}
if ( $state_2 ) {
action2();
} else {
action_not_2();
}
-Adam W.
For performance sensitive tight loops, such as parsing and HTML construction, to get the
best performance it's necessary to think about what PHP is doing on an opcode by
opcode basis.
Certain flow control patterns cannot be implemented efficiently in PHP without using
"goto". The current example in Gerrit
708880<https://gerrit.wikimedia.org/r/c/mediawiki/core/+/708880/5/includ…
comes down to:
if ( $x == 1 ) {
action1();
} else {
action_not_1();
}
if ( $x == 2 ) {
action2();
} else {
action_not_2();
}
If $x==1 is true, we know that the $x==2 comparison is unnecessary and is a waste of a
couple of VM operations.
It's not feasible to just duplicate the actions, they are not as simple as portrayed
here and splitting them out to a separate function would incur a function call overhead
exceeding the proposed benefit.
I am proposing
if ( $x == 1 ) {
action1();
goto not_2; // avoid unnecessary comparison $x == 2
} else {
action_not_1();
}
if ( $x == 2 ) {
action2();
} else {
not_2:
action_not_2();
}
I'm familiar with the cultivated distaste for goto. Some people are just parotting the
textbook or their preferred authority, and others are scarred by experience with other
languages such as old BASIC dialects. But I don't think either rationale really holds
up to scrutiny.
I think goto is often easier to read than workarounds for the lack of goto. For example,
maybe you could do the current example with break:
do {
do {
if ( $x === 1 ) {
action1();
break;
} else {
action_not_1();
}
if ( $x === 2 ) {
action2();
break 2;
}
} while ( false );
action_not_2();
} while ( false );
But I don't think that's an improvement for readability.
You can certainly use goto in a way that makes things unreadable, but that goes for a lot
of things.
I am requesting that goto be considered acceptable for micro-optimisation.
When performance is not a concern, abstractions can be introduced which restructure the
code so that it flows in a more conventional way. I understand that you might do a
double-take when you see "goto" in a function. Unfamiliarity slows down
comprehension. That's why I'm suggesting that it only be used when there is a
performance justification.
-- Tim Starling
_______________________________________________
Wikitech-l mailing list --
wikitech-l@lists.wikimedia.org<mailto:wikitech-l@lists.wikimedia.org>
To unsubscribe send an email to
wikitech-l-leave@lists.wikimedia.org<mailto:wikitech-l-leave@lists.wikimedia.org>
https://lists.wikimedia.org/postorius/lists/wikitech-l.lists.wikimedia.org/