measuring difference between single and double quotes

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post 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";
?>
Last edited by timvw on Mon Apr 17, 2006 12:05 pm, edited 1 time in total.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post 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>
Last edited by timvw on Mon Apr 17, 2006 12:10 pm, edited 1 time in total.
Gambler
Forum Contributor
Posts: 246
Joined: Thu Dec 08, 2005 7:10 pm

Post 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.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post 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 .
Gambler
Forum Contributor
Posts: 246
Joined: Thu Dec 08, 2005 7:10 pm

Post 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 /><?
?>
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

Can we conclude that the differences can be neglected performance wise?
User avatar
dbevfat
Forum Contributor
Posts: 126
Joined: Tue Jun 28, 2005 2:47 pm
Location: Ljubljana, Slovenia

Post 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. :)
User avatar
shiznatix
DevNet Master
Posts: 2745
Joined: Tue Dec 28, 2004 5:57 pm
Location: Tallinn, Estonia
Contact:

Post 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.
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post 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...
User avatar
Oren
DevNet Resident
Posts: 1640
Joined: Fri Apr 07, 2006 5:13 am
Location: Israel

Post 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.
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post 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...
User avatar
Oren
DevNet Resident
Posts: 1640
Joined: Fri Apr 07, 2006 5:13 am
Location: Israel

Post 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?
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

Post 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
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post 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.
User avatar
Oren
DevNet Resident
Posts: 1640
Joined: Fri Apr 07, 2006 5:13 am
Location: Israel

Post 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:)
Post Reply