PHP string looping
A quick hacky benchmark to measure speed of character-by-character string building in PHP. Each test (except do_nothing()) builds a string of 100,000 "*" characters. do_repeat() uses the built-in function str_repeat() so represents the most ideal possible case of optimized C code, though most parsing will not produce large arrays of the same character. ;)
do_repeat2() adds an empty for loop, demonstrating the best we're likely to see in PHP that goes character-by-character.
[edit] The assessment
Simply looping through 100,000 iterations in PHP is hella slow. Appending characters to a string with .= is the speediest PHP-based construct I could get working; it adds less than the loop overhead itself.
Pre-allocating a string and using indexed offsets is somewhat slower than the append. Working with a big array of short strings is rather slower, at least for this simple case. Copying the strings around on every operation ($result = $result . ".") gives the absolute worst results -- this should be avoided.
[edit] The results
Running on PHP 5.0.1 on an Athlon XP 2400:
Benchmarking 100 runs of do_nothing... 3.1685829162598E-06 seconds per run 315598.4951091 runs per second Benchmarking 100 runs of do_repeat... 3.054141998291E-05 seconds per run 32742.419984387 runs per second Benchmarking 100 runs of do_repeat2... 0.092702879905701 seconds per run 10.787151391815 runs per second Benchmarking 100 runs of do_prealloc... 0.14803943157196 seconds per run 6.7549570366589 runs per second Benchmarking 100 runs of do_append... 0.1359907412529 seconds per run 7.353441791602 runs per second Benchmarking 100 runs of do_combine... 3.2336623096466 seconds per run 0.30924688611325 runs per second Benchmarking 100 runs of do_array... 0.49620581150055 seconds per run 2.0152928015413 runs per second
[edit] The code
<?php
define( 'TEST_SIZE', 100000 );
function wfTime(){
$st = explode( ' ', microtime() );
return (float)$st[0] + (float)$st[1];
}
function benchmark( $function, $runs = 100 ) {
print "Benchmarking $runs runs of $function...\n";
$start = wfTime();
for( $i = 0; $i < $runs; $i++)
$function();
$delta = wfTime() - $start;
$avg = $delta / $runs;
$hertz = $runs / $delta;
print "$avg seconds per run\n";
print "$hertz runs per second\n\n";
}
function do_nothing() {
}
function do_repeat() {
$result = str_repeat( "*", TEST_SIZE );
return $result;
}
function do_repeat2() {
$result = str_repeat( "*", TEST_SIZE );
for( $i = 0; $i < TEST_SIZE; $i++ ) {
# NOP
}
return $result;
}
function do_prealloc() {
$result = str_repeat( " ", TEST_SIZE );
for( $i = 0; $i < TEST_SIZE; $i++ ) {
$result{$i} = "*";
}
return $result;
}
function do_append() {
$result = "";
for( $i = 0; $i < TEST_SIZE; $i++ ) {
$result .= "*";
}
return $result;
}
function do_combine() {
$result = "";
for( $i = 0; $i < TEST_SIZE; $i++ ) {
$result = $result . "*";
}
return $result;
}
function do_array() {
$arr = array();
for( $i = 0; $i < TEST_SIZE; $i++ ) {
$arr[$i] = "*";
}
$result = implode( $arr );
return $result;
}
benchmark( "do_nothing" );
benchmark( "do_repeat" );
benchmark( "do_repeat2" );
benchmark( "do_prealloc" );
benchmark( "do_append" );
benchmark( "do_combine" );
benchmark( "do_array" );
?>