Speed and performance myths
Created: Last updated:
Lets bust some myths about the Zend Framework's performance and its apparent lack of speed.
I read a lot that the Zend Framework is slow, lacks speed and has an overall bad performance compared to other frameworks. The usual blame and consensus is on a bloated library, inheritance, abstraction, interfaces and other stuff that ultimately just doesn't make sense me. If it would be a factor it could be measures on a single instance, but you can't because each one is such a small fraction of a millisecond. Even combined it's still nothing.
The problem is usually not the framework, and I mean any framework. The real real problem is that most people do not understand what slows down a system, i.e. what factors affect performance. Specifically they are not able to identify bottlenecks.
When they mention only some clues but never anything specific then they don't know it from cold hard facts. It's all hearsay. This very website runs the Zend Framework and ships code under 0.3 second which is pretty darn fast compared to other websites and I think I still have some room for improvements in the future. Which is entirely my fault and not the framework's problem.
Plus, it is very difficult to set benchmarks for comparing frameworks but first, lets look at bootlenecks,
If you have a problem with performance, like speed of an application or system, one of the most important things you have to identify is the bottleneck.
You can have the fastest most reliable database server in the world but when your connection to that server is bad and not optimized then your website is slowed down by that connection.
Every system is as strong as its weakest link and as fast as its slowest component.
I can easily think of about two dozen potential bottlenecks and depending on your application or system you need different tools and ways to find these bottlenecks.
To demonstrate a bottleneck in action and especially how little it takes to slow down a system, a Zend Framework application in my case, I have a perfect example. Surprisingly it has absolutely nothing to do with the framework.
Example Windows versus Linux
The example is right in front of me. I have a Windows Vista Home Premium 64-bit PC with an Intel Core Quad 2.40 GHz CPU and 6GB RAM. Installed is an older version of VMware 2.0.1 and it runs two virtual hosts. One virtual host runs Windows XP 64-bit with the XAMPP stack. The other virtual host runs CentOS 6 Linux plain vanilla without X window and an Apache (httpd) daemon.
So far, so good. Time for a little test and comparison. I measure the time in milliseconds from the first line in the index.php to the last line and print the difference as an HTML comment and the final output. This is a very simple and basic test to see how long it takes for my web application to complete the whole request.
I open a webpage from one of my Zend Framework applications on Windows and it takes ~0.85 seconds. Oh, now there is a sign for our bad Zend Framework performance. However, the very same web page on Linux takes only ~0.42 seconds.
Now, is Windows our bottleneck, Linux far superior and can we blame this simply on Windows?
No we cannot. Although the whole hardware and software configuration appears to be identical with VMware we have a different web configuration; plus I have Eclipse and other stuff running on this XP system. Not to mention that the XP system is not the latest Windows version (10 years old!) and not even an optimized server version. Unlike the CentOS virtual host without X Window which is the latest version and optimized as a server.
But wait there is more; I also mentioned the web configuration. The XP systems has an older version of XAMPP which is still running PHP 5.2, Apache 2.0 and maybe a lot of other garbage that came with XAMPP. For a fair comparison I should install the latest Windows Server version and the latest XAMPP stack. I should also make sure that the Apache and PHP configuration is the same on both systems and take a closer look at the TCP/IP configuration, like frame sizes.
Just to complete this example the same web page running on a small AWS EC2 Linux instance takes about 0.28 seconds. I wonder if there will be a difference once I move to a larger instance.
Factor of bottlenecks
As we can see in this very simple example we have a speed difference from 0.28 to 0.85 which is a factor of three (3). The very same Zend Framework application on different hardware and operating systems and different configurations.
With this example how can you compare one framework with another.
If you want to compare the Zend Framework to another framework you should really make sure you have the absolute same environment and here is the difficult part. You have to create the absolute same real world web application. Only then we have a fair comparison.
So far what I hear and see nobody has really done that in a reliable fashion. The best I have seen so far is some "Hello World" comparison which is a very bad example and I don't consider this a real world example.
Data and databases
The "Hello World" test is a very bad comparison because it avoids most of the real world bottlenecks. The Zend Framework is doing a lot of work in the bootstrap process you will not need for a "Hello World" page but for a real world web application.
The real world bottlenecks are data and especially working with the data.
With the little "Hello World" test page we don't have to query data, verify data, sanitize data and do a lot of things we do for a secure and stable web application. To compare two frameworks you have to include and handle data and work with database queries based on the request.
One of the problems inflicted by developers is using methods like fetchAll() on the mapper for large database table. If this is a large table—and maybe you don't even need all data—you have to wait for all the data being fetched from the database. Just because Zend makes it easy for your with fetchAll() to get a table doesn't mean you should not use it without any SELECT and WHERE clauses.
For the Zend Framework we even have a tool to see what is going on with our database queries. You can add or rather activate the Zend_Db_Profiler in your Zend database adapter. For detailed information see the Zend_Db_Profiler documentation with the Zend manual website.
If ... then
The main problem and performance loss is somewhere else in most Zend Framework applications, though.
It's all the ifs and thens that slows down an web application. If (!) we want a stable and secure application then (!) we have to add a lot of code to an otherwise simple and slim script.
We have to inspect, validate and understand the request which usually requires a few steps. The deeper the path or complex the request the more validations have to be done before we even know if the request is valid.
Once we understand the request we have to either return an error message or fetch the data from somewhere. Depending on your application this can be a quick and simple query to the database; like a request for a simple text document.
Many application however are a complex combination of different requests. Your application may have to check various values in the request. The request may require a special way of presentation. You may have to change or restrict the result based on who is requesting the information.
Based on some factors in the request you may have to add additional widgets or add-ons, offers or upsells and whatnot to the final page.
Inspect your Controller
To find the real bottleneck you have to carefully inspect what happens in your controller. If you have a simple Zend Framework application it all happens in your IndexController.php. Measure time in millisecond from the beginning of your controller to the end of it.
A simple way to measure the time is getting the time in preDispatch and postDispatch of the controller. There are several ways to make this work and I leave this up to you.
When you compare these measurement against the beginning and end of the whole request you will be surprised to learn that your application uses most of the time between these two measure points in the controller.
What happens or rather begins and ends in your controller is usually where your own PHP code is at work. If you use a lot of component from the library you can of course blame a lot on the library but it usually takes a lot of your own code to connect these library items. Even though you use components from the Zend Framework it is overall straight forward PHP code written by you.
Let me add the numbers here from my example with my virtual Linux server where the request takes ~0.42 seconds.
From the start of the index.php to the beginning of the IndexController it takes about ~0.1 seconds; sometimes a couple hundreds less and sometimes a couple hundreds more. Overall I can say that the whole bootstrap and routing routine takes about 1/10 of a second.
From the end of the IndexController and to the end of the index.php, that includes rendering of the view, it usually takes about 0,03 seconds. If we add these two numbers we can say that the whole MVC process of the Zend Framework on my less then perfect Linux server takes under 0.15 seconds. Now what about the difference to 0.42 seconds?
My web application doing quite a few things besides just immediately pulling the data from the database (based on the routing information) takes roughly 0.27 seconds. Although there are a few components taken from the Zend library it is mostly my code—my fault.
And frankly: the parts taken from the library? If I wouldn't have the code from the library I would have to write the same code anyway. Maybe not quite as extensive but still I would have written a comparable number of lines if not more.