views:

226

answers:

2

Q1) I'm designing a CMS (-who isn't!) but priority is being given to caching. Literally everything is cached. DB rows, DB id queries, Configuration data, processed data, compiled templates. Currently it has two layers of caching.

The first is a opcode cache or memory cache such as apc, eaccelerator, xcache or memcached. If an entry is not found in there it is then searched for in the secondary slow cache, ie php includes.

Are the opcode caches actually faster than doing a require_once to a php file with a var_export'd array of data in it? My tests are inconclusive as my development box (5.3 of XAMPP) keeps throwing errors installing any of the aforementioned programs.

Q2) The CMS has numerous helper classes that are autoloaded on demand instead of loading all files. Mostly each has a require before it so no autoloading needs to take place, however this is not the question. Because a page script can have up to 50/60 helper files included I have a feeling that if the site was under pressure it would buckle because of all the i/o that this incurs. Ignore for the moment that there is output cache in place that would remove the need for what I am about to suggest, and also that opcode caches would render this moot. What I have tried to do is join all the helper files required for the scripts execution in one single file. This is achievable and works well, however it has a side effect of greatly increasing the memory usage dramatically even though technically the same code is being used.

What are your thoughts and opinions on this?

+1  A: 

First, keep in mind that your operating system will cache files in memory if they are being accessed frequently enough.

Also, don't use require_once. It is significantly slower than require. If you aren't using an autoloader, you should be. There is no reason to be manually including files in a modern php application (very few exceptions).

50-60 helper files is crazy. Isn't there some way to combine these? Can't you put them all in a related helper class, like OutputHelper or CacheHelper? That way you only have to include the class, which, again, should be taken care of your autoloader. It sounds to me you're doing something like putting one function per file.

Opcode caching greatly reduces memory usage and execution speed, but I'm not sure what effect it has on require statements.

ryeguy
No, these files are all helper classes and not functions. Trouble is that if I use require, then you will get class redeclaration errors if the same file is included more than once. I've switched all the requires to include_once's as suggested in another thread and that does seem a little better.With regards to manually including them, they are typically not manually included, a lot are autoloaded, however if the autoloaded class is extending or an implementation then there are require statments in there to save on the autoloading.
buggedcom
@buggedcom: I am willing to bet it's more expensive to use `include_once` than it is to make the autoloader work a bit harder when you extend a class and it has to load its parent. Frameworks are very complex and large, yet none of them do manual includes.
ryeguy
@ryeguy: The way the autoloader is setup it is possible to do this. I thought doing it this way was actually better for performance?
buggedcom
@buggedcom: Not sure if I get what you're saying. If I understood you correctly, you manually include a child's parent class? For example, you have `class Widget extends AbstractWidget` and you would do `include_once 'AbstractWidget.php'` in your `Widget.php` file, right? What I meant was that yes, you're saving the autoloader from having to find `Widget.php` here, but using `(require|include)_once` is slow because PHP has to do internal checks to see if the file has been included before.
ryeguy
Yes, you've essentially understood what I am doing. I understood it to be that using the autoloader function was slow itself so hence doing the require once. So perhaps a better solution would be to role my own load function that in conjunction with autoload can see if the file requested is already loaded? I think some benchmarking is required.
buggedcom
Just done a very very quick test based on 10 pages executions loading 40 odd includes, 10 while using include_once and 10 while using autoload instead. Whilst this is fairly inconclusive, autoload was the quicker by 0.00744407176969 seconds average. now that may not sound like a lot, it infact is. I will test a roll-my-own load function and post back also.
buggedcom
A: 

Using a compiler cache like APC should help out as it will take your helper files and cache them after they are converted to opcode. That will mean the files will not only be cached but already in opcode so they do not need to be parsed and compiled each time they are required.

John Conde
Thanks but I realize this as kinda stated in the question. I was just asking because of the "what if" someone who used the cms didn't have an opcode cache. A lot of my clients hosts don't allow them because they don't officially support them (+ they do also cause segmentation faults that you have to keep an eye on)
buggedcom