In PHP switch
statements, does placing more common cases near the top improve performance?
For example, say the following function is called 1,000 times:
<?php
function foo_user ($op) {
switch ($op) {
case 'after_update':
//Some Stuff
case 'login':
//Some other Stuff
}
}
If in 990 of the 1,000 of the times the function is called the $op argument is 'login', would performance improve by having case: 'login'
above case 'after_update':
in the switch
statement? For example, would the code after case 'after_update':
be ignored if $op = login
was passed?
I've run some informal tests on this idea, but the difference has been negligible -- perhaps because the code after case: 'login'
and case 'after_update':
are both trivial. I'd prefer to avoid setting up a more extensive test with non-trivial operations if someone knows the answer outright.
This is specifically a Drupal question, but I imagine it could be addressed by anyone who is familiar with optimizing PHP.
You can see that order may matter, or it may not, depending on how the compiler implements the switch. For most good compilers, it does not matter much.
The performance is the same.
The switch statement executes line by line (i.e. statement by statement) and once PHP finds a case statement that evaluates to true, it's not only executes the code corresponding to that case statement, but also executes all the subsequent case statements till the end of the switch block automatically.
The PHP switch Statement Use the switch statement to select one of many blocks of code to be executed.
This is likely going to be called a micro optimisation. I don't believe there would be a large difference.
However, order does mean a lot to the logic of the switch case if you allow the cases to fall through, example
switch ($var) {
case 0:
case 1:
do_it();
break;
case 2:
do_it_else();
break;
}
The order is important, the case will fall through and execute any code until it hits a break.
I wouldn't be concerned about the speed of the switch case, unless you had say 100 possible cases. But if then, it'd be likely you should refactor your code.
You will need a whole lot more than 1000 cases to notice a difference, but yes, there is a difference. I wrote up a test:
function test_switch($value) {
$startTime = time() + microtime();
for ($i = 0; $i < 10000000; $i++) {
switch($value) {
case "abcdefg":
$j = $j + 1;
break;
case "hijklmno":
$j = $j + 1;
break;
}
}
$endTime = time() + microtime();
echo "Total time for argument $value: " . ($endTime - $startTime) . "<br>\n";
}
test_switch("abcdefg");
test_switch("hijklmno");
That is 10 million executions of the switch statement. The output is:
Total time for argument abcdefg: 3.99799704552
Total time for argument hijklmno: 5.38317489624
So there is a difference, but it won't be noticeable until you reach on the order of 10 million executions, depending on your processor of course.
If you do not use break;
to close each statement PHP will continue to evaluate cases until the end of the switch
block which may impact performance in a large enough block. The order then becomes important for getting the behavior you are looking for.
From PHP.Net:
The switch statement executes line by line (actually, statement by statement). In the beginning, no code is executed. Only when a case statement is found with a value that matches the value of the switch expression does PHP begin to execute the statements. PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement. If you don't write a break statement at the end of a case's statement list, PHP will go on executing the statements of the following case. For example:
<?php
switch ($i) {
case 0:
echo "i equals 0";
case 1:
echo "i equals 1";
case 2:
echo "i equals 2";
}
?>
I would caution against relying on this behavior though and use break;
for each case
as that will remove some ambiguity when you revisit the code later.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With