|PHP Classes blog||>||Why is it better to d...||>||All threads||>||WordPress and friends||>||(Un) Subscribe thread alerts|
Markku Niskanen - 2012-03-21 15:24:01
A nice introductory article. I have been planning to write one myself but so far have not had the time.
The performance myth seems to live on. I have tested a few CMS's: Drupal, Joomla, IonizeCMS and my own. Of these Drupal is procedural, Joomla object-oriented, IonizeCMS OOP+MVC and my own OOP+Smarty Objects. Of these four my own was the most lightweight and fastest (no bragging, just something I noticed). Ionize came second, Joomla third and Drupal consumed a horrible amount of resources even though being procedural. I tested memory use and the time used to get the HTML done for the front page.
The tested CMS's showed the default front page of their installation (except my own which also showed an event calendar, site news ticker and some RSS titles).
A very quick test with Wordpress revealed that its memory consumption is VERY high, amounting to 20MB+ per query and a lot of CPU. I did not have a look at its architecture but it looks pretty bad.
As for memory use I have noticed (running a couple of public servers) that some clients' small (procedural) utility function libraries with less than dozen functions consume more memory than all the classes in my CMS.
Anyhow, the procedural beasts where the slowest and heaviest of the pack and the object oriented ones the fastest and most lightweight. IonizeCMS would have done better had it not used on-the-fly parsing of templates.
It is obvious that writing a medium-size project without OOP will be very difficult to accomplish. With PHP 5.4 and 'traits' it will be even easier to write maintainable and extensible code.
Manuel Lemos - 2012-03-21 15:28:16 - In reply to message 1 from Markku Niskanen
Right the matters of performance are rarely about OOP versus global code.
The fact is that I/O operations like database accesses take so much more time to execute than any PHP code style related overhead.
Memory usage is also often related with database accesses, especially MySQL that by default buffers query results in memory before PHP code can access it.
Anyway, those performance/memory issues tend to be a distraction and are often used to fight one programming style versus another.
Markku Niskanen - 2012-03-21 20:33:13 - In reply to message 2 from Manuel Lemos
I suspected the database handling as well but I was wrong (actually there were so few queries that it gave a hint). Well, I did a kind-of breakdown of the memory usage and funny enough it seemed to be the code itself that used the memory. Having a look at APC cache it was easy to see which parts of each application were the suspects.
This does NOT reveal the whole truth but gives some idea, at least.
Cache for Drupal, for instance revealed these bytes:
So more than 20 MB bytecode was cached after the first request. This is procedural code.
The highlights for Joomla were
This might imply that a huge number of classes gets preloaded at each request.
The low-performance tagmanager needs memory and resources and probably uses quite a bit of runtime memory as well. Ionize is, however, one of the healthiest systems I have seen.
My own framework is a bit more lightweight:
Smarty3 class 242,504
templates_c 217,856 (compiled templates)
There is one thing that I want to point out: My own code is NOT optimized in any way, it just HAPPENS to compile to small bytecode. I have seen very small pieces of PHP that compile to big bytecode.
These compiled bytecodes gave the following figures. HTML means the number of HTML lines, KB is the HTML code size, SECONDS is the time to create the HTML and MAXMEM is the maximum memory usage reported by PHP:
System HTML KB SECONDS MAXMEM
<mine> 730 29.9 0.040 2040
Ionize 480 11.9 0.088 2816
Joomla 257 3.1 0.158 5376
Drupal 221 16.6 0.230 5500
The cache numbers are pretty well in line with the memory use.
I did the comparison to see whether our platform is good enough for a larger user base. No need to switch :) I will release most of the code at some point after getting rid of my 3-year project with a paying customer :)
BUT: As you said database access is a BIG factor. Having proper indexes and as few queries and writes to disk as possible will speed things up a lot.
Manuel Lemos - 2012-03-21 22:26:14 - In reply to message 3 from Markku Niskanen
One thing you should be aware is that APC uses shared memory to store compiled PHP code. Shared memory does not count as RAM usage. Shared memory is the same for all requests. So if one PHP script takes X KB of shared memory, that is not per request, that is for all requests running on the same machine.
As for database, the best thing to do is to use caching to avoid repeating queries to retrieve the same data. Caches may use files or some other persistent storage like shared memory.
Markku Niskanen - 2012-03-22 12:36:17 - In reply to message 4 from Manuel Lemos
Yes, I know the APC workings. One thing to note, however, is that APC caches the bytecodes "per directory". So if we have 20 separate installations of Drupal cached they will use 20x22 MB = 440 MB bytecode cache. In a shared environment this is more than possible and may become a problem in a small VPS, for instance. It may even render the APC cache practically useless.
My REAL point was, however, that the 'famous' systems are actually pretty memory/CPU hungry. Drupal and Wordpress - which are non-OOP systems - use the most resources and are the slowest of the pack. This is the most important notion and proves wrong the "OOP creates bloated and slow applications". OOP in PHP is technically pretty mature and has been that for years. And I suspect this was the message in your article as well:)
As you said SELECT queries are seldom a problem and there are several ways to cache the results. And Smarty cache, for instance, can be fine-tuned pretty well to cache almost everything which results in a huge speed advance.
The very things to avoid seem to be database writes. Some systems record each page fetch (or any module fetch inside a query) to a database table which may slow things down quite a bit. In my case (a XEN VPS) one single INSERT to a simple table resulted in the time spent growing from ~0.03 seconds to ~0.05 seconds - using an established DB connection. Well, XEN is not the best environment for disk I/O.