This post is in response to the
Framework Benchmarks posted three weeks ago*. I have taken the time to download the code, set up a local copy, and profile the tests performed. The results I will characterize shortly, but first I would like to discuss the validity of the benchmarks themselves.
The benchmark code involved is not the best-performing code that can be written within the CakePHP framework. No tricks are employed; it is a simple and by-the-book example of JSON View. It is important to note that performance is not necessarily the highest asset to a given framework, nor for this one in particular: we like to imagine that flexibility and speed of development are of greater primacy. It should be obvious to state that in a production environment where performance is a concern, caching is a necessity, no matter the technology employed.
That said, the benchmark results are simply embarrassing.
So, I fired up xdebug, and a few things became apparent. The average request spends the largest amount of time in App::load(). Obviously reading files from disk is going to be slow under any circumstances, and the solution is equally obvious: load fewer files from disk. The devil is assuredly in the details. Other pain points include bootstrap, the Hash class, and event dispatching.
App::load()
Both Controllers and Models take a long time to load. Related: these are deeply inherited classes. JSON View and FileLog are also up on that list. Why FileLog is loaded at all is, to me, a good question. It would be nice to be able to reduce the amount of files that are loaded and processed, but most of these don't add significantly to the time taken. The inheritance issue is much more problematic.
Hash class
This is relatively straightforward and should not require any major changes to Cake. Hash::insert and Hash::_simpleOp are slow, and I suspect that the entire class is a bit slower than it could be.
Bootstrap
The average request spends 1/3 of its time in this file. The largest chunk of that time is spent in Configure::bootstrap(). I have no idea what that is doing, but it should probably stop doing that.
Event Dispatching
This to me is the most tragic component on this list. The Events system is so very useful, and so slow! The only thing that I can think of is to not dispatch events unless it is absolutely necessary -- somehow we need to default to not doing this.
The profiler files may be viewed with WinCacheGrind on Windows, KCacheGrind on Linux, and with Webgrind on any platform with a web server installed. I think that while these benchmarks are quite unpleasant, there must surely be a lot of low-hanging fruit. It would also be nice to develop some performance tests, so that things like this won't catch us completely by surprise.
--PL
* The benchmarks have been updated twice but are still just as ugly for us.