Using the ClassMap Autoloader for Better Performance
Want to improve Zend Framework 2 performance with minimal effort? If so, come learn about the ClassMap autoloader.
Do you want a simple way to improve the performance of your Zend Framework 2 application? One that you don’t need to code and can be maintained for you at deploy or commit time? If so, come learn about the ClassMap autoloader.
Zend Framework 2’s been critiqued many times as being slow, at least slower than some of the other leading PHP frameworks. And to be fair, sometimes it’s true. But it doesn’t need to be and there are simple things you can do to improve performance of your applications.
So this post will be the first in a multi-part series looking at ways in which you can improve the performance of your Zend Framework 2 application, with only a minimum of effort.
What is an Autoloader?
If you’re not familiar with autoloaders, they’ve been around since PHP 5 and allow classes to be found by PHP when either the
class_exists() functions are called. You almost no longer need to make use of the
include() functions any longer.
Both the Standard and ClassMap autoloaders support PSR-0 compliant autoloading. Quoting the standard, that means:
- A fully-qualified namespace and class must have the following structure ()*
- Each namespace must have a top-level namespace (“Vendor Name”).
- Each namespace can have as many sub-namespaces as it wishes.
- Each namespace separator is converted to a DIRECTORY_SEPARATOR when loading from the file system.
- Each _ character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR. The _ character has no special meaning in the namespace.
- The fully-qualified namespace and class is suffixed with .php when loading from the file system.
- Alphabetic characters in vendor names, namespaces, and class names may be of any combination of lower case and upper case.
So if I’d created a module called
VideoManager and in that had requested
VideoManager\Notify\Video\EmailNotifier, assuming VideoManager is a module I’ve created, then the class will be found in
module/VideoManager/src/VideoManager/Notify/Video/EmailNotifier.php. By default, the Zend Framework libraries will be found under
The Standard Autoloader
As the name infers, it’s the standard autoloader and if no other is used it will be the fallback one used to look up the class in the available paths.
This is fine in development, as you’re experimenting and testing ideas and performance isn’t an issue. But in production, you could have a rather heavy performance penalty if you continue to use it.
The reason is that it has to search all the paths which are available to it, such as the include_path and all the module paths, when attempting to resolve the file. Depending on the number of paths available and the directory depth , this could take some time.
By default it’s setup for each module in
Module.php in the
getAutoloaderConfig() function, which I’ve got a sample of below.
Here you see that it returns an array of autoloaders, specifying only one,
Zend\Loader\StandardAutoloader. It specifies a namespace, which is the current module, and a path where the files for that namespace can be found, which will be
module/VideoManager/src, assuming the module name is VideoManager.
Let’s run Apache Bench on that configuration and see how it performs. The configuration I’m using is 200 concurrent users over 15 seconds, using the following command:
ab -c 200 -t 15 http://localhost:8080/.
I’m using the PHP cli server with only a simple site and connecting to a SQLite3 database. So there’s not a lot of overhead. Here’s the results.
You can see that it’s ok at 7.81 requests per second. Let’s see if that can be improved.
The ClassMap Autoloader
This autoloader is a much higher performing autoloader than the standard. The reason being, is because it doesn’t search the filesystem to attempt to resolve a class. Instead, as the name implies, it uses a class map, or a map of classes to their file paths to resolve the file. Here’s a small sample of what one looks like:
On the left you see the class, on the right you see the path. The array can then be searched with a
isset(). In production, you could expect this to be significantly faster.
Enabling the ClassMap Autoloader
To enable it, in
getAutoloaderConfig() we add the following to the start of the returned array:
This will add it as the first autoloader to be used and tell it to use the classmap which we’ve just generated.
Generating the Class Map
But how to keep the file up to date? You don’t want to do this by hand, for obvious reasons. But gladly you don’t have to. A utility is shipped with Zend Framework 2, which does this all for you,
classmap_autoloader.php and is available in the
This will scan a directory for all the class files and generate the classmap file automatically. Several options are available including:
- How the file will be created. If it exists, it can be overwritten or appended to
- Where to search for the class files
- Where to write the classmap file to
- Whether to sort the results
Assuming I’m in the module directory, running the command below will generate a new classmap file, called autoload_classmap.php in the root of the module.
Let’s now re-run Apache Bench to see what the performance difference is.
Ok, so the differences weren’t mind boggling, 7.81 requests per/second versus 8.10. But this is a simple test setup. But I do encourage you to try it out and see what your results are like. If you’d like more comprehensive information about the classloaders and aren’t using them in the full MVC stack, then defeinitely check out Rob Allens excellent post or this post by Hari K T.
Otherwise, if you’ve got any thoughts or questions, add them in the comments.
comments powered by Disqus