PHP why goes on n slower than using break

Pay attention to the following code:

$start = microtime(); for($i = 2; $i < 100; $i++) { for($y = 2; $y <= sqrt($i); $y++) { if($i%$y != 0) { continue; } else { continue 2; } } echo $i.','; } echo "\nFinished in " . (microtime() - $start); 

Given that the code above uses continue 2 effectively to break the inner loop and skip any post of code in the inner loop, why does the following code run faster on average when it seems to do more:

  $start = microtime(); for($i = 2; $i < 100; $i++) { $flag = true; for($y = 2; $y <= sqrt($i); $y++) { if($i%$y != 0) { continue; } else { $flag = false; break; } } if($flag === true) echo $i.','; } echo "\nFinished in " . (microtime() - $start); 

Thanks for any input.

_____ Update ____________

Thanks for the tip, but we seem to have missed it. Regardless of whether this is good programming practice, I tried to understand why the difference in performance (which is tiny but consistent) is not within the bias that I expected.

The passage of truth in a microtiter seems insignificant, since both samples are measured using the same method with the same overhead and the same inaccuracies.

More than one run was verified, which was implied by using the middle word.

To illustrate, consider the following small samples using microtime (true), which show the same pattern as when using microtime ().

I know this is a small sample, but the template is pretty clear:

Continue +0.00037288665771484 +0.00048208236694336 +0.00046110153198242 +0.00039386749267578 +0.0003662109375

Break +0.00033903121948242 +0.00035715103149414 +0.00033307075500488 +0.00034403800964355 +0.00032901763916016

Thanks for watching, and thanks for the further feedback.

______ UPDATE Further research ____________

Interestingly, if echo statements are removed from the code, then continue is faster, and in-place echo statements are interrupted faster.

Please consider the following code example and consider that the results are in conflict, depending on whether the echo statements are deleted or not:

 <?php $breakStats = array(); $continueStats = array(); ob_start(); for($i = 0; $i < 10000; $i++) { $breakStats[] = doBreakTest(); $continueStats[] = doContinueTest(); } ob_clean(); echo "<br/>Continue Mean " . (array_sum($continueStats) / count($continueStats)); echo "<br/>Break Mean " . (array_sum($breakStats) / count($breakStats)); function doBreakTest() { $start = microtime(true); for($i = 2; $i < 100; $i++) { $flag = true; $root = sqrt($i); for($y = 2; $y <= $root; $y++) { if($i%$y != 0) { continue; } else { $flag = false; break; } } } if($flag === true) echo $i . ''; return microtime(true) - $start; } function doContinueTest() { $start = microtime(true); for($i = 2; $i < 100; $i++) { $root = sqrt($i); for($y = 2; $y <= $root; $y++) { if($i%$y != 0) { continue; } else { echo $i . ''; continue 2; } } } return microtime(true) - $start; } 

Presented echo expressions:

Continue Average 0.00014134283065796 Break Mean 0.00012669243812561

Echo operators are not present:

Continue Average 0.00011746988296509 Break Mean 0.00013022310733795

Please note that by removing the echo instruction from the break and flag test, we will also remove the check ($ flag === true), so the load should decrease, but in this case, continue to win. Tue

So in a pure continuation scenario n and break + the flag seems to continue n is a faster counter. But add an equal number of identical echo operators and flags with a continuation of n.

It is logical that continue n should be faster, but I expected to see the same with echo messages present.

This is clearly the difference in the generated opcodes, and does the position of the echo statement (inner loop versus outer loop) do anyone know a way to see the generated opcodes? This, I believe, is the ultimatum that I need, as I try to understand what is happening inside the country.

Thanks:)

+4
source share
2 answers

Yes, at first the bit is faster. This is because it just jumps on continuation 2 and prints $ i.

In the 2nd example, there are more tasks ... assign the value of the variable $ flag, exit the loop, check the value of the flag, check the type of flag $ (compared), and then output $ i. It is a bit slower (simple logic).

In any case, does it have any purpose?

Some of my results are for comparison.

 0.0011570 < 0.0012173 0.0011540 < 0.0011754 0.0011820 < 0.0012036 0.0011570 < 0.0011693 0.0011970 < 0.0012790 

Used: PHP 5.3.5 @ Windows (1000 attempts; 100% was faster at first)

 0.0011570 < 0.0012173 0.0005000 > 0.0003333 0.0005110 > 0.0004159 0.0003900 < 0.0014029 0.0003950 > 0.0003119 0.0003120 > 0.0002370 

Used by: PHP 5.3.3 @ Linux (1000 attempts, 32% first: 68% seconds faster)

 0.0006700 > 0.0004863 0.0003470 > 0.0002591 0.0005360 > 0.0004027 0.0004720 > 0.0004229 0.0005300 > 0.0004366 

Used: PHP 5.2.13 @ Linux (1000 attempts, 9% first: 91% of the seconds were faster)

Sorry, I no longer have servers to test :) Now I think that it mostly depends on the hardware (and maybe it depends on the OS).

Typically: This proves that a Linux server is faster than a single run on Windows :)

+2
source

The continue 2 version is a little faster for me. But these are not the things you usually need to worry about. Consider:

 for($y = 2; $y <= sqrt($i); $y++) 

Here you calculate sqrt at each iteration. Just change this to:

 $sqrt = sqrt($i); for($y = 2; $y <= $sqrt; $y++) 

will give you a much better improvement than switching between two almost identical cycle styles.

continue 2 should be used if you find it easier for you to understand. On a computer anyway.

To find out your update regarding opcodes, see

php -d vld.active=1 -d vld.execute=0 -f foo.php

+2
source

Source: https://habr.com/ru/post/1346387/


All Articles