On Wed, 2008-08-27 at 12:27 +0200, Bernhard Kohl wrote: > tedd wrote: > > There are significant orders of magnitude difference between your results > > and mine. > > For example, it didn't make any difference if you used a comma or > > concatenation, but in my system concatenation was 15 times faster than using > > a comma. Interesting, I would have guessed it would have been the other way > > around. > > I refined the test, so that it is more random and therefore maybe more accurate. What does random have to do with the echo, concatenaton, interpolation, or heredoc functionality? I would presume these to be mutually exclusive. As such your test adds noise to the problem and is more than likely less accurate. > ------------------------------------------------------------------------------ > For all those who want to try it out, here is the code: > ------------------------------------------------------------------------------ > > <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" > "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> > <html xmlns="http://www.w3.org/1999/xhtml"> > <head> > <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> > <title>Test for Tedd</title> > </head> > <body style="font-size: small;"> > <h1>Test Results</h1> > <?php > global $iterations, $results, $test_string; > $iterations = 2048; > $iterations2 = 128; // iterations for 2nd test > $results1 = array( > "comma" => array("total_time" => 0, "count" => 0), > "concat" => array("total_time" => 0, "count" => 0), > "interpol" => array("total_time" => 0, "count" => 0), > "heredoc" => array("total_time" => 0, "count" => 0) > > ); An array? You do realize that arrays are stored as some kind of tree with O( lg n ) lookup? This means that it WILL take longer to access some of those entries than it does for others. They can't all be sitting at the root node of the tree. These tests shoul dhave been run individually. > $results2 = $results1; > $test_array = array(); > $test_string = md5(time()); // a 32 character string > $eval_strings = create_eval_strings(); > for ($i = 0; $i < $iterations; ++$i) $test_array[] = > str_shuffle($test_string); // random strings Aggain I'd like to point out that randomizing the string more than likely does nothing for the benchmark. > for ($i = 0; $i < $iterations; ++$i) test_method(rand(0,3)); A function call... to a less than simplistic function (yes simple logically, complex when benchmarks should normally be run on the simplest representation of the problem). > function test_method($method) { > $start_time = $end_time = 0; > $test_array =& $GLOBALS['test_array']; > $test_string =& $GLOBALS['test_string']; > $eval_strings =& $GLOBALS['eval_strings']; > for ($i = 0; $i < 10; ++$i) { > $j = rand(0, $GLOBALS['iterations']); > $test_array[$j] = str_shuffle($test_array[$j]); // change some arr > vals to outsmart any php speedup/cache > } > $arr2 = array(); // array for 2nd test > for ($i = 0; $i < $GLOBALS['iterations2']; ++$i) $arr2[] = > $test_array[rand(0, $GLOBALS['iterations'])]; > # 1st test will output # of iterations random strings > # 2nd test will output a sequence of #iterations2 random strings > switch ($method) { > case 0: // comma > # -----> TEST 1 <----- > ob_start(); > $start_time = microtime(true); > foreach ($test_array as $array_value) { > echo $test_string, $array_value; > } > $end_time = microtime(true); > ob_end_clean(); > $GLOBALS["results1"]["comma"]["total_time"] += abs($end_time - > $start_time)*1000/$GLOBALS["iterations"]; > ++$GLOBALS["results1"]["comma"]["count"]; > # -----> TEST 2 <----- > ob_start(); > $start_time = microtime(true); > eval($eval_strings['comma']); > $end_time = microtime(true); > ob_end_clean(); > $GLOBALS["results2"]["comma"]["total_time"] += abs($end_time - > $start_time)*1000; > ++$GLOBALS["results2"]["comma"]["count"]; > break 1; Do you mind if I scream here... output buffering, eval, internal microtime function to measure the efficiency of multiple different approaches? These are all going to add to the noise. You should use the system's time command to determine actual time spent on the process. > case 1: // concatenation > # -----> TEST 1 <----- > ob_start(); > $start_time = microtime(true); > foreach ($test_array as $array_value) { > echo $test_string.$array_value; > } > $end_time = microtime(true); > ob_end_clean(); > $GLOBALS["results1"]["concat"]["total_time"] += abs($end_time - > $start_time)*1000/$GLOBALS["iterations"]; > ++$GLOBALS["results1"]["concat"]["count"]; > # -----> TEST 2 <----- > ob_start(); > $start_time = microtime(true); > eval($eval_strings['concat']); > $end_time = microtime(true); > ob_end_clean(); > echo $eval_string."\n"; > $GLOBALS["results2"]["concat"]["total_time"] += abs($end_time - > $start_time)*1000; > ++$GLOBALS["results2"]["concat"]["count"]; > break 1; > case 2: // interpolation > # -----> TEST 1 <----- > ob_start(); > $start_time = microtime(true); > foreach ($test_array as $array_value) { > echo "{$test_string}{$array_value}"; > } > $end_time = microtime(true); > ob_end_clean(); > $GLOBALS["results1"]["interpol"]["total_time"] += abs($end_time > - $start_time)*1000/$GLOBALS["iterations"]; > ++$GLOBALS["results1"]["interpol"]["count"]; > # -----> TEST 2 <----- > ob_start(); > $start_time = microtime(true); > eval($eval_strings['interpol']); > $end_time = microtime(true); > ob_end_clean(); > $GLOBALS["results2"]["interpol"]["total_time"] += abs($end_time > - $start_time)*1000; > ++$GLOBALS["results2"]["interpol"]["count"]; > break 1; > case 3: // heredoc > # -----> TEST 1 <----- > ob_start(); > $start_time = microtime(true); > foreach ($test_array as $array_value) { > echo <<<TEST > $test_string$array_value; > TEST; > } > $end_time = microtime(true); > ob_end_clean(); > $GLOBALS["results1"]["heredoc"]["total_time"] += abs($end_time - > $start_time)*1000/$GLOBALS["iterations"]; > ++$GLOBALS["results1"]["heredoc"]["count"]; > # -----> TEST 2 <----- > ob_start(); > $start_time = microtime(true); > eval($eval_strings['heredoc']); > $end_time = microtime(true); > ob_end_clean(); > $GLOBALS["results2"]["heredoc"]["total_time"] += abs($end_time - > $start_time)*1000; > ++$GLOBALS["results2"]["heredoc"]["count"]; > break 1; > } > } > function create_eval_strings() { // returns the eval strings for the 4 methods > $strings = array(); > $eval_string = 'echo'; // comma > for ($i = 0; $i < $GLOBALS['iterations2']; ++$i) $eval_string .= ' > $arr['.$i.'],'; > $eval_string{strlen($eval_string) - 1} = ';'; > $strings['comma'] = $eval_string; > $eval_string = str_replace(', ', '.', $eval_string); // concatenation > $strings['concat'] = $eval_string; > $eval_string = 'echo "'; //interpolation > for ($i = 0; $i < $GLOBALS['iterations2']; ++$i) $eval_string .= > '{$arr['.$i.']}'; > $eval_string .= '";'; > $strings['interpol'] = $eval_string; > $eval_string = "echo <<<TEST\n"; // heredoc > for ($i = 0; $i < $GLOBALS['iterations2']; ++$i) $eval_string .= > '$arr['.$i.']'; > $eval_string .= "\nTEST;"; > $strings['heredoc'] = $eval_string; > return $strings; > } > function get_result(&$result) { > $buffer = ""; > foreach ($result as $key => $value) { > $avg_time = $value['total_time']/$value['count']; > $buffer .= " > <h3>{$key} Method</h3> > <p><strong>Number of Echoes:</strong> {$value['count']}</p> > <p><strong>Total time:</strong> {$value['total_time']} milliseconds</p> > <p><strong>Average time:</strong> {$avg_time} milliseconds</p> > "; > } > return $buffer; > } > $result1 = get_result($results1); > $result2 = get_result($results2); > echo <<<RESULTS > > <h2>Results for $iterations cycles of echoing a 32-character string > with a random 32-character string $iterations times:</h2> > $result1 > <h2>Results for echoing $iterations2 random 32-character string > $iterations times:</h2> > $result2 > RESULTS; > ?> > </body> > </html> I don't mean to beat down on you, but this is not a good benchmark. I will follow this post with a proper benchmark. Cheers, Rob. -- http://www.interjinn.com Application and Templating Framework for PHP -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php