In my index.php file I always load some classes used later. From profiler it states it sometimes can take about 20% of entire code. Is there any improvement that can make this process faster?
I would try to make this list of classes shorter, but app is very big and checking all dependencies will be costly.
Op-code caches such as APC and eAccelerator store a compiled version of your scripts in a cache. This dramatically reduces memory usage and loading time for frequently used static scripts.
While using an opcode cache (such as APC) will reduce the impact of loading/parsing/compiling the class, you'll still be loading them all on every page load & doing whatever initialization accompanies a require_once() call. If you were to set up an autoload function then the classes won't be loaded until your code actually needs to use them. There's a little overhead involved in using a class autoloader but it makes the code easier to maintain.
As always, YMMV, so benchmark your application to see if it's worthwhile in your case.
You might want to look at apc php.net/apc
Related
In my recent projects a decided for a lazy, on demand load of class files with an autoloader. What is the performance hit of using an autoloader pattern for including class files as opposed to including the needed class files or all class files? Will it impact precompiling and caching?
In the majority of configurations, it will give a performance boost.
With just "out of the box" PHP, every file is compiled on demand when you include it. If you include every file on every request, every file is compiled on every request.
With OpCache enabled, each file is cached into shared memory when first compiled. However, that memory may get full, and there may be files that you never actually use, so compiling based on usage is still likely to be better.
With preloading, you can pre-populate OpCache's cache of compiled files. Classes from preloaded files will automatically be available to all processes anyway, so just won't trigger the autoloader.
The only time an autoloader could be costly is if you have multiple places that the same class could be defined, and the autoloading function checks the disk for which ones exist. That's why Composer has options to optimize its generated autoloading routines. If you're not using Composer already, I highly recommend you do so.
Is there a way to define constants that boot into memory when the PHP process starts on the server? If so, can it be done with arrays, classes, and functions as well?
Before people start listing the different ways of declaring things that will be available across pages and scopes: I'm not asking this from a coding convenience, but rather a performance perspective.
It seems like a waste to keep loading things that never change, from pages or databases etc, on every script execution. Being a server-side process, I would think PHP has some way to read things into memory once and have them always available.
What you are looking for is an opcode cache. Opcode caches work by storing the compiled contents of PHP files in shared memory, then using that data to short-circuit the standard code parsing process when the file is included/required in the future.
The canonical opcode cache at this point is the PHP opcache extension, but a number of other opcode caches exist, including APC and XCache.
Opcode caches do not cache data from databases. There are other extensions which you can use to assist in this process, though, such as APCu which stores them in shared memory, or memcached which stores them in an external process. None of this is automatic, though, as caching data from a database requires some application knowledge to know what is useful to cache, and to handle cache invalidation when you update the database.
In general php is a single treaded environment and it does not actually run constantly (unlike java). Php starts working only when receives a command to do so. Then it parses the code into opcode and eventually executes it. And that technically happens on every request (or CLI command).
However, there are several ways how you can cache the opcode with not much efforts with APC: http://www.php.net/manual/en/book.apc.php
I hope this is not a completely stupid question. I have searched quite a bit for an answer, but I can't find (or recognise) one exactly on point.
I understand that functions in PHP are not parsed until actually run. Therefore, if I have a large class with many functions, only one of which requires a large include file, will I potentially save memory if I only include the "include file" within the function (as opposed to at the top of the class file)?
I presume that, even if this would save memory, it would only do so until such time as the function was called, after which the memory would not be released until the current script stopped running?
Many Thanks,
Rob
I love this saying: "Make it work and then, if needed, make it fast." -some good programmer?
In most cases you would probably be better off focusing on good OOP structure and application design then speed. If you server is using something like Zend Optimizer having all your methods in a single file won't make any difference since it is all pre-compiled and stored in memory.(It's more complicated then this but you get the idea)
You can also load all your include files when apache starts. Then all the functions are loaded in memory. You wouldn't want to do that while developing unless you like to restart Apache every time you make a code change. But when done on production servers it can make a huge difference. And if you really want to make things fast you can write the code in C++ and load it as a module for Apache.
But in the end... do you really need that speed?
Yes it will, but be sure that the function doesn't depend on any other functions included in the parent. The memory consumption is also dependent on a couple things, from the size of the file itself to the amount of virtual memory it requires with variable setting and proper garbage collection protocols.
If the function is inside a class, it's called a method, and it might depend on its class to extend another class.
Just some things to consider. Always include the bare minimum.
Don't save memory on such cases unless you really need it, save development time. Memory is usually cheap but development/supoort time isn't. Use php opcode cacher like eAccelerator or APC, it will increase speed of execution because all files will be pre-compiled and stored in memory.
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?
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.
Looks like you just have no idea what you want to cache (and why).
You just cannot compare "opcode cache" and "require_once". Opcode cache will cache required code as well as other code.
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.
I agree with ryeguy. require_once is slower than require or include because it has to log every include and check against it. If your only doing one require/include (which you should be for classes) then you don't need require_once or include_once.
Autoloading is great for optimization. As you only will load in classes when needed. So if your app has 500 classes, but only needs 15 to run a certain page/script. Then only those 15 get loaded. Which is nice.
If you take a peak at any big framework. You will notice that they have migrated to using autoloaders. They use to use require_once at the last moment like this example from the Zend Framework Version 1.
require_once 'Zend/Db/Exception.php';
throw new Zend_Db_Exception('Adapter name must be specified in a string');
Zend Framework Version 2 is going to be using auto loaders instead. I believe this is the fastest and it's also the easiest to code for.
I'm currently implementing memcached into my service but what keeps cropping up is the suggestion that I should also implement APC for caching of the actual code.
I have looked through the few tutorials there are, and the PHP documentation as well, but my main question is, how do I implement it on a large scale? PHP documentation talks about storing variables, but it isn't that detailed.
Forgive me for being uneducated in this area but I would like to know where in real sites this is implemented. Do I literally cache everything or only the parts that are used often, such as functions?
Thanks!
As you know PHP is an interpreted language, so everytime a request arrives to the server it need to open all required and included files, parse them and execute them. What APC offers is to skip the require/include and parsing steps (The files still have to be required, but are stored in memory so access is much much faster), so the scripts just have to be executed. On our website, we use a combination of APC and memcached. APC to speed up the above mentioned steps, and memcached to enable fast and distributed storing and accessing of both global variables (precomputed expensive function calls etc that can be shared by multiple clients for a certain amount of time) as well as session variables. This enables us to have multiple front end servers without losing any client state such as login status etc.
When it comes to what you should cache... well, that really depends on your application. If you have a need for multiple frontends somewhere down the line, I would try to go with memcached for such caching and storing, and use APC as an opcode cache.
APC is both an opcode cache and a general data cache. The latter works pretty much like memcached, whereas the opcode cache works by caching the parsed php-files, so that they won't have to be parsed on each request. That can generally speed up execution time up quite a bit.
You don't have to implement the opcode caching features of APC, you just enable them as a php module.
APC cache size and other configuration information is here.