Thursday, January 21, 2010

More fun with CakePHP

Livemocha has been using CakePHP for almost 3 years now. We have done multiple iterations of performance improvements. In past posts, I mentioned CakePHP's problem with some view helper classes. Now, I want to cover few more finds.
1. Initializing models takes forever.

I don't have the exact number on hand. When I ran a profiler on our home page, which is pretty much static except a few logic around session and auto login handling, about 30% of the time were taken by Cake trying to initialize models. After digging around a bit, I found out that instead of listing all necessary models used in the controller in $this->uses, I should initialize them individually in each action.
2. A lot of caching code are just not optomized
Latest Cake (1.2) support in memory cache such as APC. However, old Cake only suppose local file caching. When Cake 1.2 was released, majority of the Cake framework code still just use the old file based caching system. This includes model caching and view caching. Disk seed is extremely slow comparing to memory lookup, it's even slower than network IO if the data size is small (under 2 K). A lot of people have ran those tests before, I am not going to list the results here. I modified Cake code to have it to use APC for caching models and views.
3. is almost useless as it is
It sounds like a great idea to be able mark a portion of the view to be not cacheable while the rest of the view is cached. However, if you read the fine print in Cake document, you'll see that controller action is not executed if the view is cached. It makes sense since Cake just bypass the controller code and go straight to the cached view. If this is the case, what is the need of having this noncache block? You can't supply dynamic data to a view, then why does the view need to be dynamic? A little thing that one can try is to add some code to retrieve data in beforeFilter, which is executed if the callback flag is set to true for a view cache. However, nobody would push any db logic in beforeFilter. Again, I updated Cake code to take a list of callback functions and execute them before it tries to render the view. This way, data retrieving can be done in small functions and can be share in the controller.

No comments: