Performance Tuning in PHP

       PHPCAMP 2008
            th
          20 Sept.

        Jignesh Thummar
 <jignesh.thumma...
Anatomy of PHP

       PHP File            ●
                               This cycle happens
                           ...
Opcodes
                                         0 EXT_STMT

                                         1 ASSIGN            ...
Opcode/Compiler cache
●
    Each PHP script (also for included files)
    compiled only once and store into cache
●
    du...
Opcode/Compiler cache
   PHP File

    Opcode                    Cache
    Cacher

                hit/store
   Zend
  Com...
APC
●
    Alternate PHP Cache
●
    A free, open source and robust framework
    for caching and optimizing PHP
    interm...
Installation
$pecl install APC
OR Source Compilation
#wget http://pecl.php.net/get/APC
#tar -zxvf APC-3.0.x.tar.gz
#cd APC...
Enable APC
●
    edit php.in : extension=apc.so
●
    restart apache


Web console to monitor APC Info
copy apc.php from a...
.ini directives
●
    apc.shm_size = 30 (in MB)
●
    apc.stat = 1 (by default)
    -   check if files has been modified o...
more .ini directives
–   apc.ttl = 0 (by default)
     Time to Live in cache - seconds
–   apc.write_lock = 1 (by default)...
APC user cache
●
    bool apc_add(string $key, mixed $var [, int $ttl ])
●
    bool apc_store(string $key, mixed $var [, i...
page cache with APC
<?php
     $key = quot;PAGE::quot;.$_SERVER['REQUEST_URI'];
     $pagecontents = apc_fetch($key);
    ...
handling constants through APC
●
     bool apc_define_constants(string $key, array $constants
     [, bool $case_sensitive...
more functions
●
    bool apc_compile_file ( string $filename )
●
    bool apc_clear_cache ([ string $cache_type ] )
●
   ...
other opcode cacher
●
    XCache : http://xcache.lighttpd.net
●
    IonCube: http://www.ioncube.com/sa_encoder.php
●
    Z...
Benchmarking
Apache Bench
 ‣ ab utility bundled with Apache
http_load
 ‣ http://www.acme.com/software/http_load/
Siege
 ‣ ...
Apache Bench
$ab -c 20 -n 50 <webserver_url>

Concurrency Level:    20
Time taken for tests: 0.48937 seconds
Complete requ...
http_load

$http_load -rate 20 -seconds 5 <file_name>

99 fetches, 2 max parallel, 9702 bytes, in 5.00098 seconds
98 mean ...
Siege
$siege -b -r 20 -t 5S <server_url>

Transactions:              677 hits
Availability:              100.00 %
Elapsed ...
serving static contents
●
  Apache's mod_php is designed for dynamic contents.
●
  Every Apache child used fair chunk of m...
Lets tune PHP code
include/require_once - once more

lstat64(quot;/srv/www/htdocs/incl_testquot;, {st_mode=S_IFDIR|0755, st_size=4096, ...}) ...
file path problem
– While it is convenient and easy to do include “foo.php”
  and have it work, internally.
– it leads to ...
include_path



my include_path is
quot;.:/usr/share/php5:/usr/share/php5/PEAR:/srv/www/quot;

How to fix this?
sessions
●
    session.auto_start = 1 (by default 0)
●
    PHP's session extension by default store
    sessions in to eac...
sessions
●
    PHP's default session handler is file system
●
    instead, it can be stored into cache
●
    let's say in ...
static keyword
●
    makes them accessible without needing an
    instantiation of the class
●
    so it's faster
●
    pu...
Class Constants
●
    define( ) is expensive
●
    Class Constants are parsed at compile time.
    So no execution overhea...
miss use of Constants
●
    $foo[name] = 'Jignesh';
●
    converted into strtolower
●
    hash lookups
●
    E_NOTICE erro...
for() loop optimization
Don't use functions in for() loop.
<?php
      for ( $i = 1; $i < count($array); $i++ ) { }
?>
ins...
which is faster?
What’s the difference between:
      isset($user['NAME'])
            and
  array_key_exists('NAME', $use...
Performance Tips
●
    Mostly people have only one solution
●
    habitual to use DATABASE for information storage
●
    I...
What to do, when you are stuck?


●
    Use Benchmarking Tools
●
    Find bottleneck in your code
●
    It might take time...
Finally




Premature optimization is the root of all evil.
              - Donald Knuth
Resources




http://pecl.php.net/apc
Thanks




Any other idea?
Upcoming SlideShare
Loading in …5
×

Performance Tuning in PHP

42,150 views

Published on

Published in: Technology
  • Ich denke, die meisten Performance-Probleme begehen PHP bzw. Web Entwickler immer noch auf der Datenbank und durch fehlendes Caching. Dazu habe ich in meinem Blog mal einen Artikel geschrieben: http://www.kammerath.net/php-performance-tuning.html
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Performance Tuning in PHP

  1. 1. Performance Tuning in PHP PHPCAMP 2008 th 20 Sept. Jignesh Thummar <jignesh.thummar@gmail.com>
  2. 2. Anatomy of PHP PHP File ● This cycle happens for all included files not only for main() Zend Compiler script. ● Generally most of Execution at Zend Engine the time consumption take place at Compiler. End User
  3. 3. Opcodes 0 EXT_STMT 1 ASSIGN !0, 'Enjoy+the+PHPCamp%2C+' <?php 2 EXT_STMT $greet = 'Enjoy the PHPCamp, '; 3 ASSIGN !1, 'Jignesh' $name = 'Jignesh'; 4 EXT_STMT 5 ZEND_ISSET_ISEMPTY_VAR 1 ~2 'name' if(isset($name)){ 6 JMPZ ~2, ->11 $say = $greet . $name; 7 EXT_STMT }else{ 8 CONCAT ~3 !0, !1 9 ASSIGN !2, ~3 $say = $greet . 'human'; 10 JMP ->14 } 11 EXT_STMT echo $say; 12 CONCAT ~5 !0, 'human' ?> 13 ASSIGN !2, ~5 14 EXT_STMT 15 ECHO !2 Opcodes generated using Vulcan Logic 16 EXT_STMT Disassembler (VLD) by Derick Rethans. http://pecl.php.net/packages/VLD/ 17 RETURN 1 18* ZEND_HANDLE_EXCEPTION
  4. 4. Opcode/Compiler cache ● Each PHP script (also for included files) compiled only once and store into cache ● during the next request it will not compile again but directly pick it up from cache for execution ● reduce file I/O (stats calls) as it is being executed from the cache(memory) rather than disk ● the fastest and easiest solution for faster execution
  5. 5. Opcode/Compiler cache PHP File Opcode Cache Cacher hit/store Zend Compiler fetch opcodes Parse/Execute Opcodes End User
  6. 6. APC ● Alternate PHP Cache ● A free, open source and robust framework for caching and optimizing PHP intermediate code. ● maintained by core PHP developers ● users Yahoo! Facebook Wikipedia and many more
  7. 7. Installation $pecl install APC OR Source Compilation #wget http://pecl.php.net/get/APC #tar -zxvf APC-3.0.x.tar.gz #cd APC-3.0.x #phpize #./configure #make #make install #cp modules/apc.so /full/path/to/ext/apc.so Windows user Download it from : http://pecl4win.php.net/
  8. 8. Enable APC ● edit php.in : extension=apc.so ● restart apache Web console to monitor APC Info copy apc.php from apc source directory to document root
  9. 9. .ini directives ● apc.shm_size = 30 (in MB) ● apc.stat = 1 (by default) - check if files has been modified on every request - if apc.stat = 0, requires restart webserver on update or apc_clear_cache() - use include('/webroot/conf.php') instead of include('conf.php') ● apc.filters = <regex> a comma separated POSIX regex. default value is “-” ● apc.cache_by_default = true false - files are only cached if matched by a positive filter
  10. 10. more .ini directives – apc.ttl = 0 (by default) Time to Live in cache - seconds – apc.write_lock = 1 (by default) only one process at a time instead of waiting on a lock – apc.num_files_hint = 1000 (by default) maximum number of files expect to be stored in memory – apc.max_file_size = 1M (by default) maximum file size that will be allowed in the apc cache – apc.file_update_protection=1(protect for 2 sec) – apc.include_once_override = 0 (by default)
  11. 11. APC user cache ● bool apc_add(string $key, mixed $var [, int $ttl ]) ● bool apc_store(string $key, mixed $var [, int $ttl ]) ● mixed apc_fetch(string $key) ● bool apc_delete(string $key) .ini settings apc.user_ttl = 0 apc.user_entries_hint = 4096
  12. 12. page cache with APC <?php $key = quot;PAGE::quot;.$_SERVER['REQUEST_URI']; $pagecontents = apc_fetch($key); if($pagecontents) { echo $pagecontents; exit; } ob_start(); // write your code $pagecontents = ob_get_flush(); apc_store($key, $pagecontents); ?>
  13. 13. handling constants through APC ● bool apc_define_constants(string $key, array $constants [, bool $case_sensitive]) ● bool apc_load_constants(string $key [,bool $case_sensitive]) <?php $constants = array( 'NAME' => 'Jignesh', 'AGE' => 24, 'LOCATION' => 'Pune', ); apc_define_constants('jignesh_info', $constants); apc_load_constants('jignesh_info'); echo NAME,',',AGE,',',LOCATION; ?>
  14. 14. more functions ● bool apc_compile_file ( string $filename ) ● bool apc_clear_cache ([ string $cache_type ] ) ● array apc_cache_info ([string $cache_type[,bool $limited ] ] ) ● array apc_sma_info ([ bool $limited ] )
  15. 15. other opcode cacher ● XCache : http://xcache.lighttpd.net ● IonCube: http://www.ioncube.com/sa_encoder.php ● Zend Platform: http://www.zend.com/en/products/platform/ ● Turck MMCache: http://turck-mmcache.sourceforge.net/index_old.html ● EAccelerator: http://www.eaccelerator.net/
  16. 16. Benchmarking Apache Bench ‣ ab utility bundled with Apache http_load ‣ http://www.acme.com/software/http_load/ Siege ‣ http://www.joedog.org/JoeDog/Siege Benchmark PEAR package ‣ http://pear.php.net/package/Benchmark
  17. 17. Apache Bench $ab -c 20 -n 50 <webserver_url> Concurrency Level: 20 Time taken for tests: 0.48937 seconds Complete requests: 50 Non-2xx responses: 52 Total transferred: 10504 bytes HTML transferred: 0 bytes Requests per second: 1021.72 [#/sec] (mean) Time per request: 19.575 [ms] (mean) Time per request: 0.979 [ms] (mean, across all concurrent requests) Transfer rate: 204.34 [Kbytes/sec] received
  18. 18. http_load $http_load -rate 20 -seconds 5 <file_name> 99 fetches, 2 max parallel, 9702 bytes, in 5.00098 seconds 98 mean bytes/connection 19.7961 fetches/sec, 1940.02 bytes/sec msecs/connect: 0.470556 mean, 0.635 max, 0.221 min msecs/first-response: 1.40029 mean, 2.106 max, 1.175 min HTTP response codes: code 200 -- 99
  19. 19. Siege $siege -b -r 20 -t 5S <server_url> Transactions: 677 hits Availability: 100.00 % Elapsed time: 5.84 secs Data transferred: 5.39 MB Response time: 0.13 secs Transaction rate: 115.92 trans/sec Throughput: 0.92 MB/sec Concurrency: 14.67 Successful transactions: 677 Failed transactions: 0 Longest transaction: 0.99 Shortest transaction: 0.04
  20. 20. serving static contents ● Apache's mod_php is designed for dynamic contents. ● Every Apache child used fair chunk of memory when it's executed with mod_php. ● Serving static content like image, JS, CSS, HTML etc. with mod_php is more costly ● Other option: lighttpd thttpd Boa And nowadays S3 (Amazon Web Services)
  21. 21. Lets tune PHP code
  22. 22. include/require_once - once more lstat64(quot;/srv/www/htdocs/incl_testquot;, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat64(quot;/srv/www/htdocs/incl_test/a.phpquot;, {st_mode=S_IFREG|0644, st_size=39, ...}) = 0 open(quot;/srv/www/htdocs/incl_test/a.phpquot;, O_RDONLY) = 4 lstat64(quot;/srv/www/htdocs/incl_testquot;, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat64(quot;/srv/www/htdocs/incl_test/a.phpquot;, {st_mode=S_IFREG|0644, st_size=39, ...}) = 0 open(quot;/srv/www/htdocs/incl_test/a.phpquot;, O_RDONLY) = 4 In PHP 5.2>= this will allow PHP to avoid opening the file twice.
  23. 23. file path problem – While it is convenient and easy to do include “foo.php” and have it work, internally. – it leads to significant overhead in system. – Whenever possible you should use full paths, that require no resolution in PHP. getcwd(quot;/srv/www/htdocs/perf_demoquot;, 4096) = 26 lstat64(quot;/srv/www/htdocs/incl_test/a.phpquot;, {st_mode=S_IFREG|0644, st_size=39, ...}) = 0 open(quot;/srv/www/htdocs/incl_test/a.phpquot;, O_RDONLY) = 4 getcwd(quot;/srv/www/htdocs/perf_demoquot;, 4096) = 26 lstat64(quot;/srv/www/htdocs/perf_demo/b.phpquot;, {st_mode=S_IFREG|0644, st_size=39, ...}) = 0 open(quot;/srv/www/htdocs/perf_demo/b.phpquot;, O_RDONLY) = 4 Generate system calls using $strace -e trace=file php <file_name.php>
  24. 24. include_path my include_path is quot;.:/usr/share/php5:/usr/share/php5/PEAR:/srv/www/quot; How to fix this?
  25. 25. sessions ● session.auto_start = 1 (by default 0) ● PHP's session extension by default store sessions in to each file within single directory. ● many files into one directory reduce access speed ● instead, store session in different directory ● session.save_path = “N;/var/lib/php5” ● N – no. of directory level e.g. /tmp/4/b/1/e/3/sess_14879g
  26. 26. sessions ● PHP's default session handler is file system ● instead, it can be stored into cache ● let's say in memcache ● session.save_handler = memcache session.save_path = “tcp://127.0.0.1:11211” ● using APC's add/fetch/delete
  27. 27. static keyword ● makes them accessible without needing an instantiation of the class ● so it's faster ● public static function a( ) is faster compare to public function a( ) ● quick benchmark for it.
  28. 28. Class Constants ● define( ) is expensive ● Class Constants are parsed at compile time. So no execution overhead. ● faster lookup due to smaller hash. ● benchmark for it
  29. 29. miss use of Constants ● $foo[name] = 'Jignesh'; ● converted into strtolower ● hash lookups ● E_NOTICE error message generated ● temporary string being generated on the during the execution ● And of course it's slower ● Let's benchmark for it.
  30. 30. for() loop optimization Don't use functions in for() loop. <?php for ( $i = 1; $i < count($array); $i++ ) { } ?> instead use, <?php $count = count($array); for ( $i = 1; $i < $count; $i++ ) { } ?>
  31. 31. which is faster? What’s the difference between: isset($user['NAME']) and array_key_exists('NAME', $user) Let's generate opcodes, more opcode less performance
  32. 32. Performance Tips ● Mostly people have only one solution ● habitual to use DATABASE for information storage ● Improper use of this resource can lead to significant and continuously increasing performance loss. ● Try to cache at different level ● Avoid reg-ex, PHP's string functions are faster ● Avoid magic calls - __get/__set/__autoload/__call. ● There are lots of PHP's built in functions; PEAR, PECL packages ● chances are there what you need is already available
  33. 33. What to do, when you are stuck? ● Use Benchmarking Tools ● Find bottleneck in your code ● It might take time to do optimization ● There is no any golden rule for it ● make your hand dirty
  34. 34. Finally Premature optimization is the root of all evil. - Donald Knuth
  35. 35. Resources http://pecl.php.net/apc
  36. 36. Thanks Any other idea?

×