coding styles (apache/cli/multithreaded) - test result

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

Post Reply
User avatar
nathanr
Forum Contributor
Posts: 200
Joined: Wed Jun 07, 2006 5:46 pm

coding styles (apache/cli/multithreaded) - test result

Post by nathanr »

Hi Guys,

I thought I'd do some quick testing on php to see which method(s) of coding work best..

Platform
  • PHP Version 5.2.4
    Linux (Ubuntu 6.06 LTS)
    Dual Core AMD Opteron(tm) Processor 175 (2194.87 MHz) w/ 2GB Ram
Tested Under:
  • CLI & Apache 2.0.55 (PHP Via Apache 2.0 Handler)
The basic test.. a simple call to this

Code: Select all

sha1(microtime(true).rand(1,2300))
run 1000000 (one million) times, each test was carried out 5 times to get some idea of fluctuation


Test 1 - inline:

Code: Select all

for($b=0;$b<1000000;$b++) {
	sha1(microtime(true).rand(1,2300));
}
Via Apache:
4.69 : 4.65 : 4.65 : 4.66 : 4.65
Via CLI:
4.73 : 4.70 : 4.72 : 4.74 : 4.72


Test 2 - function:

Code: Select all

function t() {
	sha1(microtime(true).rand(1,2300));
}
for($b=0;$b<1000000;$b++) {
	t();
}
Via Apache:
5.16 : 5.12 : 5.12 : 5.12 : 5.12
Via CLI:
5.20 : 5.30 : 5.22 : 5.24 : 5.23


Test 3 - OO Method 1:

Code: Select all

class test {
	public function t() {
		sha1(microtime(true).rand(1,2300));
	}
}
$o = new test;
for($b=0;$b<1000000;$b++) {
	$o->t();
}
Via Apache:
5.44 : 5.40 : 5.39 : 5.41 : 5.38
Via CLI:
5.47 : 5.39 : 5.34 : 5.38 : 5.36


Test 4 - OO Method 2:

Code: Select all

class test {
	public function __construct() {
		$this->c();
	}
	public function c() {
		for($i=0;$i<1000000;$i++) {
			sha1(microtime(true).rand(1,2300));
		}
	}
}

$o = new test;
Via Apache:
4.65 : 4.61 : 4.62 : 4.63 : 4.61
Via CLI:
4.67 : 4.70 : 4.73 : 4.76 : 4.75


=========================================================

Sub Conclusion
Suprisingly Apache was marginally faster in all tests carried out, the 2 fastest (and almost identical) methods were:
  • Test 1 - Inline
    Test 4 - OO Method 2
with almost identical timings, however the benefits of OO design over inline coding in real world applications are clear for all.


=========================================================

Will Multithreading via the CLI speed things up?
To get some results I repeated tests 1 & 4 via the cli, however this time multithreaded (5 worker threads + launcher thread) - the results are as follows:

Test 1 - inline
4.70 : 4.71 : 4.71 : 4.72 : 4.70
Test 2 - OO Method 2
4.73 : 4.71 : 4.73 : 4.74 : 4.72

Rather unsuprisingly multithreading was no faster.. why?
The test function used is very processor intensive, so no matter which method we use, the computer has to do the same amount of work, thus we can't speed it up without upgrading the hardware. The question remains then, when do we multithread our applications, The answer lies in the following tests.


Multithreaded vs Non Threaded

The Test:
50x file_get_contents() on a manual page at uk.php.net [ single thread vs multithreaded (5 worker threads + launcher thread) ]

Single Thread:
52.55 : 53.33 : 52.86
Multithreaded:
16.42 : 16.49 : 16.58


=========================================================

Conclusion
Personally I've gathered that as I'd assumed previously, most applications can be fully optimised and run as quick as can be by sticking to standard PHP5 OO practises; The only time this can be improved is when we need to work with third party datasources or applications that run slower than our machine can handle, under these circumstances it's safe to say that multithreading will vastly speed things up.


=========================================================

One Final Lesson
You can speed up your applications very simply by making the smallest of changes; use single quotes instead of double quotes around all your strings. Check this out:

The Test:
Double Quotes:

Code: Select all

for($i=0;$i<5000000;$i++) {
	$testdata = "a normal $i string";
}
Single Quotes

Code: Select all

for($i=0;$i<5000000;$i++) {
	$testdata = 'a normal '.$i.' string';
}
The Results

Double Quotes:
5.43 : 5.57 : 5.53 : 5.57 : 5.43

Single Quotes:
4.49 : 4.51 : 4.52 : 4.51 : 4.49

Shaved 1 second (20%) off my very simply script simply by using single quotes!
(why? php parses everything in double quotes for variables, cut that parsing out and save a tonne of processing time)


Cheers,

nath
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

One Final Lesson
You can speed up your applications very simply by making the smallest of changes; use single quotes instead of double quotes around all your strings.
Double quotes is ok as long as you don't have any variables inside (php will not try to interpolate a string with no variables in it).
User avatar
nathanr
Forum Contributor
Posts: 200
Joined: Wed Jun 07, 2006 5:46 pm

Post by nathanr »

Weirdan wrote:Double quotes is ok as long as you don't have any variables inside (php will not try to interpolate a string with no variables in it).
Indeed, this said I tend to stick to single quotes myself as a personal "best practise" - well noted though!
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

Suprisingly Apache was marginally faster in all tests carried out, the 2 fastest (and almost identical) methods were:
Why surprising? Apache module is loaded once and resides in memory as far I remember. CGI needs to be fired up each time, that takes up clock cycles. :)
Double quotes is ok as long as you don't have any variables inside (php will not try to interpolate a string with no variables in it
I do believe it's the tokenizer which figures out whether the string uses interpolation (infact I'm sure of it) however the tokenizer would still need to test whether the string contained an interpolated variable if the string is double quoted, so there is still additional processing when you use double quotes over single quotes.
Indeed, this said I tend to stick to single quotes myself as a personal "best practise" - well noted though!
Absolutely! It drives me nutts when I see PHP code littered with double quotes for no reason. It's bad practice, like allocating memory and not freeing it when done inside compiled languages. There was a time I never used double quotes, but after some consideration I had a change of heart and use them in some instances, especially in SQL queries as readability is improved 10 fold.
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post by stereofrog »

Weirdan wrote:
One Final Lesson
You can speed up your applications very simply by making the smallest of changes; use single quotes instead of double quotes around all your strings.
Double quotes is ok as long as you don't have any variables inside (php will not try to interpolate a string with no variables in it).
Yes, but php parser still needs to scan the string looking for the variable. This adds some overhead, no matter whether variables are actually used.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

stereofrog wrote:
Weirdan wrote:
One Final Lesson
You can speed up your applications very simply by making the smallest of changes; use single quotes instead of double quotes around all your strings.
Double quotes is ok as long as you don't have any variables inside (php will not try to interpolate a string with no variables in it).
Yes, but php parser still needs to scan the string looking for the variable. This adds some overhead, no matter whether variables are actually used.
I think you mean the lexer/tokenizer. ;)
User avatar
nathanr
Forum Contributor
Posts: 200
Joined: Wed Jun 07, 2006 5:46 pm

Post by nathanr »

Hockey wrote:
stereofrog wrote:
Weirdan wrote: Double quotes is ok as long as you don't have any variables inside (php will not try to interpolate a string with no variables in it).
Yes, but php parser still needs to scan the string looking for the variable. This adds some overhead, no matter whether variables are actually used.
I think you mean the lexer/tokenizer. ;)
I actually tested that the other night aswell

50,000,000 calls to "some string" followed by the same to 'some string' - timings where identical.. so whatever checks to see if a variables in the string is either amazingly efficient or...?

:?
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

I'd be interested to see the results with the object instantiation being included in the for() loop, but I am too lazy to do it myself. :P
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

nathanr wrote:50,000,000 calls to "some string" followed by the same to 'some string' - timings where identical.. so whatever checks to see if a variables in the string is either amazingly efficient or...?
Tokenizers are usually pretty efficient...so the difference would be negligible considering the code isn't that much more sophisticated...

Basically if a single quote character is found by the tokenizer, it can probably get away with a simple loop which does nothing but test for the existance of a closing single quote, once found, everything in between the opening/closing single quotes become a single token entity.

Likewise, if a double quoted character is found, the logic is a little more sophisticated...

Now you need to tokenize everything that could exist between a double quoted string, so your looking out for things like:

Code: Select all

"Hello $string"
"Hello ${this->something}"
And whatever else is allowed in an interpolated string...handling those "extra" characters will probably burn more clock cycles...as the tokenizer needs slightly more intelligence to deal with double quoted strings...

Why your results were identical...it's hard to say. Unless you profile on a system with no background running processes, you will never get a truely accurate representation...it's been a long while since I talked about anything "profiling" so pardon any errors. However, profiling on PHP is probably not very accurate to begin with. PHP requires the influence of many other sub-systems all of which could affect the results of a profiling test.

Consider that, when I say something is going to run slower than the next, I'm speaking of clock cycles...PHP doesn't let you measure code execution at that fine level (which is most accurate). PHP relies on high performance timers...which in this case is the microtime() and it only returns timings accurate to one-millionth of a second.

So when your profiling apples and oranges, they may very well result in both apples...only when you compare something like oranges and elephants do the results really show.

The point is, that more sophisticated logic absolutely requires more clock cycles than something more trivial...and clock cycles are what you actually burn, the more you use, the less are available for other tasks...

If it's common knowledge that using double quotes is indeed slower (even if negligible) why use them when you don't have too? Its like eating a chocolate bar or a bag of chips...both satisfy your cravings nicely...but one will result in more fat around your belly than the other.

When I see double quotes and no sign of interpolation...I immediately think the developer was lazy or totally ignorant to the idea. Amatuer-ish in my opinion.

Cheers :)
User avatar
nathanr
Forum Contributor
Posts: 200
Joined: Wed Jun 07, 2006 5:46 pm

Post by nathanr »

Hockey wrote:
nathanr wrote: If it's common knowledge that using double quotes is indeed slower (even if negligible) why use them when you don't have too? Its like eating a chocolate bar or a bag of chips...both satisfy your cravings nicely...but one will result in more fat around your belly than the other.

When I see double quotes and no sign of interpolation...I immediately think the developer was lazy or totally ignorant to the idea. Amatuer-ish in my opinion.

Cheers :)
indeed, I feel the same way myself (they must be lazy/ignorant), unless wrapping up a mysql string.. but still:

Code: Select all

$sql = "SELECT * FROM table WHERE this='".$that."'";
however I would like to get back to the point that OO coding is far more efficient than "the old ways"
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post by stereofrog »

nathanr wrote:
50,000,000 calls to "some string" followed by the same to 'some string' - timings where identical.. so whatever checks to see if a variables in the string is either amazingly efficient or...?

:?
You got it wrong, I'm afraid. Using double quotes (without variables) affects the compiler, not executor, just because executor has no clue about which quotes was used. So, if you compile once and execute many times, like this

Code: Select all

(loop 50000 times) echo 'foo';
(loop 50000 times) echo "foo";
you won't see any difference. Try running the test with compilation repeated at every iteration, e.g.

Code: Select all

(loop 50000 times) eval(" 'foo'; ");
(loop 50000 times) eval(" "foo";  ");
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

You have to remember that the Tokeniser runs during compilation so looping over something that's already tokenised won't show any differences. You just get a set of string tokens. Now if you forced compilation on every single loop instead...
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

Which is what stereofrog said in the post I missed when typing...;)
Post Reply