Actually, on an Intel XEON X7560 ( 8 x 2.26 Ghz ), the slow down with this operation is huge.
Running the following code will actually show it.
<?php
//
for($xx=0;$xx<=1000;++$xx) {
$i = 0;
//a:
$z = microtime(1);
while($i <= 10000) {
//print "xx";
++$i;
}
$q = microtime(1);
$i = 0;
$$z = microtime(1);
a:
if ( $i >= 10000 ) goto z;
++$i; goto a;
z:
$$q = microtime(1);
($t = $q - $z) && ( $$t = $$q - $$z ) && $p = ( ($t / $$t) * 100 );
//print "\r\n" . ($t = $q - $z) . " <---> " . ( $$t = $$q - $$z ) . " ~ " . $p;
//goto a;
//print "\r\n";
}
print "Average: " . $p . "\r\n";
?>
<?PHP // Code originally written by (tweston AT coldsteelstudios DOT com) on 06-OCT-2010
$start = microtime(true);
$i = 0;
StartOfLoop:
++$i;
if($i < 10000000) goto StartOfLoop;
$start = microtime(true) - $start;
$$start = microtime(true);
$i = 0;
while($i < 10000000){
++$i;
}
$$start = microtime(true) - $$start;
print "\r\n";
print ( ( $$start / $start ) * 100 );
?>
Output, here:
Average: 51.841435141196 // for $i <= 10000
60.688755174503 // for $i <= 10000000
goto
El operador goto puede ser usado para saltar a otra sección en el programa. El punto de destino es especificado mediante una etiqueta seguida de dos puntos y la instrucción es dada como goto seguida de la etiqueta del destino deseado. Este goto no es completamente sin restricciones. La etiqueta de destino debe estar dentro del mismo fichero y contexto, lo que significa que no se puede saltar fuera de una función o método, ni se puede saltar dentro de uno. Tampoco se puede saltar dentro de cualquier clase de estructura de bucle o switch. Se puede saltar fuera de estos y un uso común es utilizar un goto en lugar de un break multi-nivel.
Example #1 Ejemplo de goto
<?php
goto a;
echo 'Foo';
a:
echo 'Bar';
?>
El resultado del ejemplo sería:
Bar
Example #2 Ejemplo de goto en un bucle
<?php
for($i=0,$j=50; $i<100; $i++) {
while($j--) {
if($j==17) goto end;
}
}
echo "i = $i";
end:
echo 'j alcanzó 17';
?>
El resultado del ejemplo sería:
j hit 17
Example #3 Esto no funcionará
<?php
goto loop;
for($i=0,$j=50; $i<100; $i++) {
while($j--) {
loop:
}
}
echo "$i = $i";
?>
El resultado del ejemplo sería:
Fatal error: 'goto' into loop or switch statement is disallowed in script on line 2 (Error fatal: 'goto' hacia el interior de un bucle o sentencia switch no esta permitido en el script en la línea 2)
Note:
El operador goto está disponible a partir de PHP 5.3.
About the comparison in the previous post between goto and while, goto is NOT as fast as while, it is always slower for about 25%.
In my tests by using the code below, with the addition of a for loop I get:
goto: 0.0558710098267
while: 0.0439591407776
for: 0.0468330383301
In another test PC I have seen goto being even 50% slower.
In a challenge of myself for a college class I decided to use the goto to remove all while loops from my code. It was actually easy, and AS FAST as While loops.
<?PHP
$start = microtime(true);
$i = 0;
StartOfLoop:
$i++;
if($i < 1000000) goto StartOfLoop;
echo microtime(true) - $start.PHP_EOL;
$start = microtime(true);
$i = 0;
while($i < 1000000){
$i++;
}
echo microtime(true) - $start.PHP_EOL;
?>
Remember if you are not a fan of wild labels hanging around you are free to use braces in this construct creating a slightly cleaner look. Labels also are always executed and do not need to be called to have their associated code block ran. A purposeless example is below.
<?php
$headers = Array('subject', 'bcc', 'to', 'cc', 'date', 'sender');
$position = 0;
hIterator: {
$c = 0;
echo $headers[$position] . PHP_EOL;
cIterator: {
echo ' ' . $headers[$position][$c] . PHP_EOL;
if(!isset($headers[$position][++$c])) {
goto cIteratorExit;
}
goto cIterator;
}
cIteratorExit: {
if(isset($headers[++$position])) {
goto hIterator;
}
}
}
?>
