PHP is interpreted, PHP code is parsed and translated to opcodes (primitive instructions — akin to assembly language — that the PHP engine executes directly) every time it executes. An opcode cache eliminates that rework, making PHP applications faster.
Of course, an opcode cache will not help your site if your bottleneck in not CPU or memory. For example, if your bottleneck is in the database, or disk, the opcode cache will not directly help. However, since scripts start and end faster than without one, you may experience less contention in some cases.
Among available free opcode caches, we have :
-
APC: Alternative PHP Cache. A free opcode cache maintained by PHP code developers.
-
eAccelerator, a free fork of the now abandoned Turck MMCache.
-
XCache. A free project by lighttpd.
With several servers running Ubuntu 8.04.01 LTS, Apache 2.2.8 and PHP 5.2.4 I have found that neither eAccelerator nor XCache are stable. In a matter of a day or so, you will get segmentation faults in Apache 2. Well you can watch the segmentation faults in apache error log and put the server back on when that happens . But it’s kind of a pain , so I went for APC . On the contrary, APC — currently using 3.0.19 — is very stable and never experiences segmentation faults.
APC is maintained by core PHP developers, including Rasmus Lerdorf and others. APC does not utilize a disk cache, unlike both eAccelerator and Xcache (although it is configurable). Xcache is a viable option, specially if you find installing APC daunting.
But it’s important to note that APC can perform poorly if you don’t give it enough memory to cache all of the code that your site uses. So, changing APC to use 64 MB of shared memory instead of the default 30 MB should be all right. APC uses this memory to cache the parsed and tokenized scripts for later calls.
Now let’s install APC . This assumes you’ve already installed the default LAMP Stack in Ubuntu.
Open a terminal and type :
sudo apt-get install php-pear php5-dev apache2-prefork-dev build-essential && sudo pecl install apc && sudo apt-get remove php5-dev apache2-prefork-dev
Now let’s edit the configuration file of apc. On your command prompt type :
gksudo gedit /etc/php5/conf.d/apc.ini
add these settings to the file :
extension=apc.so apc.apc.stat = 0 apc.include_once_override = 1 apc.shm_size = 64
and restart apache 2 :
sudo /etc/init.d/apache2 restart
Now, let’s test an application. Choose an application or two to test. You can use your own code . I used phpMyAdmin for the sample. I assume you’ve already installed phpMyAdmin.
Running a benchmark
The Apache HTTP Web server ships with a utility named ab, short for Apache HTTP server benchmarking tool. Use ab to automate a large number of requests for PHP pages.
The ab utility is simple to use: Provide a repeat count and a URL. The ab utility requests that URL many times over and returns statistics. Because APC is already enabled, the first benchmark will show performance with acceleration.
Before you run ab, point your browser to http://localhost/phpmyadmin/. Visiting this page once loads all the PHP code used to render the page into the cache. Now, run the benchmark shown below, iterating 100,000 times.
ab -n 100000 http://localhost/phpmyadmin/
Here is part of the output on my local :
Time taken for tests: 25.857 seconds Complete requests: 100000 Failed requests: 0 Write errors: 0 Non-2xx responses: 100000 Total transferred: 64000000 bytes HTML transferred: 35000000 bytes Requests per second: 3867.47 [#/sec] (mean) Time per request: 0.259 [ms] (mean) Time per request: 0.259 [ms] (mean, across all concurrent requests) Transfer rate: 2417.17 [Kbytes/sec] received
The statistics of interest are requests per second and the total time to complete all the tests. For the former, a higher value is better; for the latter, lower is better.
Now, disable APC by editing the apc.ini file :
gksudo gedit /etc/php5/conf.d/apc.ini
comment out all the lines :
;extension=apc.so ;apc.apc.stat = 0 ;apc.include_once_override = 1 ;apc.shm_size = 64
and restart apache 2 :
sudo /etc/init.d/apache2 restart
Now run the benchmarch again :
ab -n 100000 http://localhost/phpmyadmin/
here is the output on my local :
Concurrency Level: 1 Time taken for tests: 26.579 seconds Complete requests: 100000 Failed requests: 0 Write errors: 0 Non-2xx responses: 100000 Total transferred: 64000000 bytes HTML transferred: 35000000 bytes Requests per second: 3762.32 [#/sec] (mean) Time per request: 0.266 [ms] (mean) Time per request: 0.266 [ms] (mean, across all concurrent requests) Transfer rate: 2351.45 [Kbytes/sec] received
Here, with APC disabled, the number of requests per second fell, reflecting that the Apache server took longer for each request. The time to run the entire suite of tests climbed, as well.
Although this is a simple benchmark — the phpMyAdmin connection to the database could have been disabled to limit processing time to interpreting PHP alone — and not highly scientific, it does demonstrate what you can achieve with APC. For a tiny investment (and, thankfully, no need to recompile PHP or Apache), APC can yield a relatively large return. The more complex your code, the greater the possible benefits.


