this is interesting, I'd like to see a comparison with foreach vs. for too - just out of curiousity :) Also the $var == "" kind of suprised me, didn't know it was that bad, although I guess this does rarely happen since most probably use empty anyway.
The $var == "" issue is more understandable when you realize that PHP attempts to do type coercion to test comparison for all data types, while the equality operator (triple equals, ===) does not attempt to do type coercion.
Also, foreach(range(1, 1000 * 1000) as $i) will execute at roughly the same speed as for($i = 0, $count = 1000 * 1000; $i < $count; $i++), so the difference is negligible.
What am I supposed to learn from these numbers? They are interesting to look at, but I don't have enough information. Exactly what version of php is running, and how is it configured? What does the "Index" field signify? Where can I find the code?
While fun to look at and calculate, it also doesn't mean a lot for most applications. I would argue that data fetching from DBs or caches will be the majority of execution time.
Database access latency will always trump any language design issues, except in extreme cases. This article does make some of those cases obvious, especially since they are easily-overlooked programming mistakes.
Database access latency will always be an important factor of _latency_ .
That doesn't prevent anyone from coding stuff that requires 20 times less application servers while using the same amount of database (+caching) servers.
The very idea that because the DB call takes a while to complete, we can waste even more CPU cycles is a complete misunderstanding of real world use cases.
But then, the very use of PHP means that you don't give a shit about execution time or server costs at all.
Large web apps do often spend a lot of time manipulating strings and arrays in memory. It's absolutely true and I've seen it myself several times -- a performance penalty that is measurable and noticeable to users.
But that pales in comparison to the overhead of a Database call, or even a call to Redis or Memcached.
I've read (from sources I trust) that a database call on a modern stack like .Net or JVM is 4 orders of magnitude slower than a local method call. Think about that. So if the time you spend brushing your teeth is a local method call, the entire next day is a database query.
I can't remember the source here but the information is available with a few minutes of coding or googling.
And to the caching point -- having data cached locally in memory is great, but you can't trust that.
I'm saying that having a stale cache won't be a problem for an application that is designed around the fact that you will occasionally have stale data.
Intuitively the for loop should be a lot fast as it isn't assigning anything each loop. Although in your example it may be slower because the count($users) would be ran on each iteration of the loop.
I get what you mean, but it might be helpful to translate it for everybody else:
Foreach is doing an assignment in each iteration, robryan is right. But PHP variables are copy-on-write so $user is, until modified, just an entry in the symbol table which is very fast.
And that for() loop also has an assignment -- the incrementer.
Yeah I know, done purposefully to see how MUCH slower this is. This is how the majority of code is written in the wild, rarely do you see the `count()` pulled outside of the `for()`.
This is simply unfair, should the language maintainers be held accountable for user behaviour?
A more interesting and fairer topic is whether PHPs count() is considerably slower than python's len()
This chart is also useful to find different ways to do the same thing, so you can choose to use what is more readable or functions you didn't know about.
I got excited at first because I thought it was a standalone script that benchmarked a server. Does anybody know of a script that will score a server based on cpu/io/memory/etc? Would be a great way to see if a server is properly configured or what kind of performance to expect from a cloud solution.
The difference between php-5.2 (the version used), php-5.3, and php-5.4 is quite vast for each version, especially since php-5.4 basically cut memory usage/execution time by a third at worst (or directly by half at best) when compared to php-5.3.
This is purely anecdotal but I use PHP for large scripts doing lots of inserts/deletes (>100,000) from databases and relatively simple logic.
Depending on the ORM (or otherwise) it may have some level of caching, so the best performance would be using the PHP functions/classes directly (eg: PDO/MongoCollection/Redis).
In addition to the above, PHP extensions would be extremely preferable to pure-PHP libraries for database interaction simply because the extensions will be written in C and lack the overhead of the language.
Do you have any links to the bugs? We use 5.4 in production and haven't had any issues with APC, so I'm curious if we're missing anything relevant to our use case.
If I were writing a PHP parser, then I would convert double-quoted strings of the form "foo $bar baz" to 'foo '.$bar.' baz' when the script is first parsed. So executing the string concatenation in a loop would have no performance difference, because the string is only parsed the first time.
That's just a guess, though, having not actually looked at the code myself.
Definitely microseconds, most of my scripts with database interaction and all fully complete in around 50 milliseconds which would be impossible if string comparison took 2 milliseconds.
I got this site bookmarked from a long time ago so I do not know what is the PHP version tested. Adding it because it seems to contain quite alot of different tests.
In general you can't hoist the length check out of the loop because of the possibility that the length might change during the loop. Proving that the length doesn't change during the loop is quite difficult; in general this requires alias analysis.
You can't trust benchmarks, unless you've either seen the code or trust the person posting the benchmark enough that he benched correctly. It's easy to benchmark something other than what you think you are benchmarking.
They're implemented using the same data structure and given the language semantics (keys can be any scalar type intermingled horribly), how would you improve that?
In PHP they actually check the length of an array at every invocation of count(). As far as I can see the numeric value for length isn't stored anywhere.
48 comments
[ 3.2 ms ] story [ 97.7 ms ] threadAlso, foreach(range(1, 1000 * 1000) as $i) will execute at roughly the same speed as for($i = 0, $count = 1000 * 1000; $i < $count; $i++), so the difference is negligible.
While fun to look at and calculate, it also doesn't mean a lot for most applications. I would argue that data fetching from DBs or caches will be the majority of execution time.
People keep saying that, and I would like to see some numbers for that also.
The DB dataset could be already cached in memory, for example.
That doesn't prevent anyone from coding stuff that requires 20 times less application servers while using the same amount of database (+caching) servers.
The very idea that because the DB call takes a while to complete, we can waste even more CPU cycles is a complete misunderstanding of real world use cases.
But then, the very use of PHP means that you don't give a shit about execution time or server costs at all.
But that pales in comparison to the overhead of a Database call, or even a call to Redis or Memcached.
I've read (from sources I trust) that a database call on a modern stack like .Net or JVM is 4 orders of magnitude slower than a local method call. Think about that. So if the time you spend brushing your teeth is a local method call, the entire next day is a database query.
I can't remember the source here but the information is available with a few minutes of coding or googling.
And to the caching point -- having data cached locally in memory is great, but you can't trust that.
You can if you design around handling a possibly-stale cache.
Are you disputing the premise or just disagreeing for the sake of it?
http://www.slideshare.net/quipo/profile-your-php-application...
http://blip.tv/phpnw/phpnw10-lorenzo-alberton-profile-your-p...
Intuitively the for loop should be a lot fast as it isn't assigning anything each loop. Although in your example it may be slower because the count($users) would be ran on each iteration of the loop.
Foreach is doing an assignment in each iteration, robryan is right. But PHP variables are copy-on-write so $user is, until modified, just an entry in the symbol table which is very fast.
And that for() loop also has an assignment -- the incrementer.
http://coderwall.com/p/il1tog
Fix that:
This is purely anecdotal but I use PHP for large scripts doing lots of inserts/deletes (>100,000) from databases and relatively simple logic.
In addition to the above, PHP extensions would be extremely preferable to pure-PHP libraries for database interaction simply because the extensions will be written in C and lack the overhead of the language.
You're using outdated APC code. Update to the latest, it resolves issues with the 5.4 line. We use it in production, zero issues.
That's just a guess, though, having not actually looked at the code myself.
2 milliseconds to compare two strings seems awfully slow.
But anyway the interesting number is how many times it's slower compared to an equivalent code.
http://net-beta.net/ubench/
person who wrote this should be fired
How? This is not a trivial optimization for a compiler.
Numeric arrays in PHP are AS SLOW as associative array, that's pure fail and one of the reasons PHP::fannkuch is so slow.
In PHP they actually check the length of an array at every invocation of count(). As far as I can see the numeric value for length isn't stored anywhere.
It's not count() that's benchmarked here, its the difference between "$a < $b" and "$a < function_call($b)".