Page 3 of 4

Posted: Sat Apr 15, 2006 8:15 pm
by timvw
I've changed the test a bit: http://timvw.madoka.be/programming/php/ ... quotes.txt

Code: Select all

<?php
ini_set('error_reporting', E_ALL);
ini_set('display_errors', TRUE);

function microtime_float() {
	list($usec, $sec) = explode(' ', microtime());
	return ((float)$usec + (float)$sec);
}

function benchmark_quotes($loops = 1000000) {
	$times = array();
	for ($i = 0; $i < 6; ++$i) {
		$times[$i] = 0;
	}

	$name = 'timv';
	$age = 25;
	
	for ($i = 0; $i < $loops; ++$i) {

		$j = 0;

		$start = microtime_float();
		echo sprintf('My name is %s and i\'m %d years old.<br>' . "\n", $name, $age);
		$end = microtime_float();
		$times[$j++] += ($end - $start);

		$start = microtime_float();
		echo sprintf("My name is %s and i'm %d years old.<br>\n", $name, $age);
		$end = microtime_float();
		$times[$j++] += ($end - $start);

		$start = microtime_float();
		echo 'My name is ' . $name . ' and i\'m ' . $age . ' years old.<br>' . "\n";
		$end = microtime_float();
		$times[$j++] += ($end - $start);

		$start = microtime_float();
		echo "My name is $name and i'm $age years old.<br>\n";
		$end = microtime_float();
		$times[$j++] += ($end - $start);

		$start = microtime_float();
		echo "My name is {$name} and i'm {$age} years old.<br>\n";
		$end = microtime_float();
		$times[$j++] += ($end - $start);

		$start = microtime_float();
		echo 'My name is ' , $name , ' and i\'m ' , $age , ' years old.<br>', "\n"; 
		$end = microtime_float();
		$times[$j++] += ($end - $start);
	}

	return $times;
}

function print_times($times) {
	for ($i = 0; $i < count($times); ++$i) {
		echo 'Results for ' . $i . ': ' . $times[$i] . '<br>' . "\n";
	}
}

$times = array();
$runs = 5;
for ($i = 0; $i < $runs; ++$i) {
	$times[] = benchmark_quotes(pow(10, $i + 1));
}
for ($i = 0; $i < $runs; ++$i) {
	echo 'Results for ' . pow(10, $i + 1) . ' loops:' . "\n";
	print_times($times[$i]);
	echo "\n";
}

echo "Done.\n";
?>

Posted: Sat Apr 15, 2006 8:25 pm
by timvw
And offcourse results :)

PHP 4.3.10-16 (cli) (built: Aug 24 2005 20:25:01)
ults for 0: 0.0020301342010498<br>
Results for 1: 0.0019931793212891<br>
Results for 2: 0.0016262531280518<br>
Results for 3: 0.001856803894043<br>
Results for 4: 0.0016987323760986<br>
Results for 5: 0.0054888725280762<br>

Results for 100 loops:
Results for 0: 0.013308763504028<br>
Results for 1: 0.012649297714233<br>
Results for 2: 0.013978481292725<br>
Results for 3: 0.013944387435913<br>
Results for 4: 0.034903526306152<br>
Results for 5: 0.043781995773315<br>

Results for 1000 loops:
Results for 0: 0.070047378540039<br>
Results for 1: 0.066958904266357<br>
Results for 2: 0.12278199195862<br>
Results for 3: 0.081486701965332<br>
Results for 4: 0.077747583389282<br>
Results for 5: 0.18140554428101<br>

Results for 10000 loops:
Results for 0: 0.59532713890076<br>
Results for 1: 0.57208323478699<br>
Results for 2: 0.55661082267761<br>
Results for 3: 0.69993376731873<br>
Results for 4: 0.69578814506531<br>
Results for 5: 1.4997856616974<br>

Results for 100000 loops:
Results for 0: 6.2008361816406<br>
Results for 1: 6.0405580997467<br>
Results for 2: 5.9289400577545<br>
Results for 3: 7.3196721076965<br>
Results for 4: 7.2005059719086<br>
Results for 5: 15.339821577072<br>
PHP 5.1.2 (cli) (built: Jan 11 2006 16:40:00)
Results for 10 loops:
Results for 0: 0.001950740814209<br>
Results for 1: 0.001539945602417<br>
Results for 2: 0.001716136932373<br>
Results for 3: 0.0020339488983154<br>
Results for 4: 0.0017731189727783<br>
Results for 5: 0.0031125545501709<br>

Results for 100 loops:
Results for 0: 0.050579309463501<br>
Results for 1: 0.086180448532104<br>
Results for 2: 0.055390119552612<br>
Results for 3: 0.091173410415649<br>
Results for 4: 0.051587343215942<br>
Results for 5: 0.10812425613403<br>

Results for 1000 loops:
Results for 0: 0.060803890228271<br>
Results for 1: 0.060267686843872<br>
Results for 2: 0.06127405166626<br>
Results for 3: 0.070644378662109<br>
Results for 4: 0.067854404449463<br>
Results for 5: 0.14215326309204<br>

Results for 10000 loops:
Results for 0: 0.63306069374084<br>
Results for 1: 0.60441327095032<br>
Results for 2: 0.6046462059021<br>
Results for 3: 0.73074197769165<br>
Results for 4: 0.73758554458618<br>
Results for 5: 1.5227286815643<br>

Results for 100000 loops:
Results for 0: 6.6000764369965<br>
Results for 1: 6.3330221176147<br>
Results for 2: 6.101734161377<br>
Results for 3: 7.6772193908691<br>
Results for 4: 7.2836928367615<br>
Results for 5: 15.331125974655<br>

Posted: Mon Apr 17, 2006 11:32 am
by Gambler
BTW, I heard that this is faster than concatenation:

Code: Select all

echo $str1, $str2, $str3;
This works only with echo, though. And I'm not entirely sure about how much speed do you get. But the idea is that you do not allocate bigger string for each concatenation.

Posted: Mon Apr 17, 2006 12:05 pm
by timvw
My intention was to test , in the last case, but obviously i've forgot to replace all . by ,

Fixed! :)

Which makes me wonder about the test, because this doesn't seem to indicate that , is faster than .

Posted: Mon Apr 17, 2006 3:34 pm
by Gambler
Sorry, but the test seems to be unreliable. I jsut tried it, then swapped two last tests. It did not have expected outcome. It seems that overhead of the test framework is significanctly higher than of the test itself.

This is more reliable way to test performance:

Code: Select all

<?php
$stime = mtime();
$disableTimer = FALSE;

for ($i=0; $i<100000; ++$i) {
     //...
}

$etime = mtime();
$ttime = $etime - $stime;
if (!$disableTimer) {
    echo "<hr />Page generated in $ttime seconds.";
}
function mtime() {
    $mtime = explode(" ", microtime());
    return $mtime[1] + $mtime[0];
}
?>
If you try this, you will see that the difference between quotes, heredoc, concatenation, arguments, and sprintf is negligeble. Heck, on 100k runs the difference between various ways of outputting string is less than dispersion of different runs of the same test.

And the winner is...

Code: Select all

<?php
?>My name is <?=$name?> and I'm <?=$age?> years old.<br /><?
?>

Posted: Mon Apr 17, 2006 4:38 pm
by timvw
Can we conclude that the differences can be neglected performance wise?

Posted: Mon Apr 17, 2006 5:58 pm
by dbevfat
Yes, please do.

I mean -- it's a waste of time! A single fopen operation (or a database query) is slower than 10,000 loops with strings in single (or double or tripple) quotes? But even that db query is nothing compared to a few seconds that user waits for the whole page to download. And you wouldn't use PHP in speed-critical applications, would you? ;)

I'll stick to:
1) make sure it works,
2) check if you really need optimization,
3) only then benchmark,
4) and only then optimize. (you'll fnd out that it never has to do anything with quotes)

Time is too valuable to lose on things like this. :)

Posted: Mon Apr 17, 2006 6:18 pm
by shiznatix
Yes, please do.

I mean -- it's a waste of time!
negative, this is not a waste of time but some good knowledge (at least for me). I have had scripts that use that many loops and you need to save as much time as possible. I have always used single quotes because I thought they where faster but turns out there is no difference. Good to know.

Posted: Tue Apr 18, 2006 4:18 am
by Maugrim_The_Reaper
Who does profile by the way? Any Zend Studio or XDebug fanboys? ;)

First of all I think the discussion headed down the path of immeasurable differences. I know one set of quotes over another may be faster/slower, the same as for varying concatenation methods, increment methods, even require methods (if you are a faithful disciple of Rasmus). However, nitpicking over something which at the end of the day (borrowing the "mileage varies" adage) is likely only a tiny miniscule probably unmeasurable difference must be a waste of time.

If I took any application, enabled the XDebug extension (see PECL), captured a few dozen cachegrind records and analysed each in turn looking for optimisation issues - I seriously doubt functions using lots of double-quotes (let alone single-quotes) would be listed. I'd expect to see my database's connect() function near the top - the rest would likely be 10-20 function calls which make up the vast majority of execution/compile time. They're the ones I'd consider optimising on the basis their optimisation would have the greatest impact on improving performance.

After that it's down to diminishing returns - would the time optimising a piddling little 0.1 second function be justified by the resulting improvement? Would my time not be better spent using the optimisations suggested so far to see if refactoring can cut out or reduce the frequency of sub-optimal code execution?

The last "big" optimisaton tip was the require() vs require_once() argument raised by Rasmus. Talk of significant differences and speed ups were reported across the blogosphere supported by benchmarks. Oddly my profiling of an application with over 40 classes (and about 45 require_once() occurances) showed the aggregate time spent on require_once() was negligible. Putting aside the obvious poor practice of using the _once() functions to replace knowing what's really included and how often, such an optimisation isn't worth my time correcting. Quoting is significantly more complex - therefore it's definitely not worth even considering seriously.

That said - I'm sure there are cases where it is a valuable optimisation. I just don't see a specialised case being the common experience...

Posted: Tue Apr 18, 2006 4:55 am
by Oren
shiznatix wrote:negative, this is not a waste of time but some good knowledge (at least for me). I have had scripts that use that many loops and you need to save as much time as possible. I have always used single quotes because I thought they where faster but turns out there is no difference. Good to know.
I'm with shiznatix - "you need to save as much time as possible"
Maugrim_The_Reaper wrote:would the time optimising a piddling little 0.1 second function be justified by the resulting improvement?
I said that before - even 0.0001 second counts, if you have this 0.0001 second inside a 1M times loop that would become 100 seconds!
Will you wait 100 seconds for a page to load? I bet that you won't even wait for just 10 seconds.

Posted: Tue Apr 18, 2006 4:58 am
by Maugrim_The_Reaper
Maugrim_The_Reaper wrote:That said - I'm sure there are cases where it is a valuable optimisation. I just don't see a specialised case being the common experience...
That's not a common scenario however. The point is it's rarely going to make a huge difference to the overall application unless it IS in a loop that drags it into the region of seconds...

Posted: Tue Apr 18, 2006 6:08 am
by Oren
Maugrim_The_Reaper wrote:That's not a common scenario however.
Well, on this forum we have more than 250,500 posts. Isn't it a common scenario?

Posted: Tue Apr 18, 2006 6:18 am
by malcolmboston
if you are having problems with the "massive loop / multi loop" scenario then i would first and foremost start looking at other ways of doing what your trying to do as i have built several large-scale app's and have never really had this problem, but thats what the planning stage is for....

my $0.02

Posted: Tue Apr 18, 2006 6:20 am
by Maugrim_The_Reaper
256,327 at last check...;)

The real question however is whether altering quotes in phpBB will affect any measurable performance gain... And whether it poses an actual problem at the moment? I'm not saying it won't - only that the difference would (probably) not be justified by the time spent making the optimisation...

That may be acceptable in an open source project of course - but something on a budget could see overruns from such enthusiasm.

Posted: Tue Apr 18, 2006 6:49 am
by Oren
Well I have a database with more than 10M rows (go here if you don't know what I'm talking about) so I can now play with it and make some tests with it :D

I'll make few test with single and double quotes on this database and I'll post the results here.
Do you guys have any suggestions for a test? (don't tell me to try and print it all or something like that - that would take hours :wink:)