Pro Yearly is on sale from $80 to $50! »

[PHPBenelux 2015] PHP Performance Tuning: Prepare for Ludicrous Speed!

[PHPBenelux 2015] PHP Performance Tuning: Prepare for Ludicrous Speed!

There's a saying "hardware is cheaper than developers", but this only holds true if you treat your hardware with the respect it deserves.

Learn how to diagnose, confirm and fix bottlenecks in your application using XHProf and Xhgui.

After an in-depth look at how to use these tools, we'll take a practical look at actually using them to achieve measurable (~20%) performance improvements in a popular open source project.

Fee39f0c0ffb29d9ac21607ed188be6b?s=128

Davey Shafik

January 23, 2015
Tweet

Transcript

  1. PHP Performance Tuning Prepare for Ludicrous Speed!

  2. Proprietary and Confidential •Community Engineer at Engine Yard •Author of

    Zend PHP 5 Certification Study Guide, Sitepoints PHP Anthology: 101 Essential Tips, Tricks & Hacks & PHP Master: Write Cutting Edge Code •A contributor to Zend Framework 1 & 2, phpdoc, & PHP internals • Original creator of PHAR/ PHP_Archive • Lead for PHPWomen US •@dshafik Davey Shafik
  3. Let’s start a conversation about mental health in tech mhprompt.org

  4. Hardware is Cheap, Programmers are Expensive “ ” Source: Jeff

    Atwood
  5. But only if you respect the hardware “ ” Source:

    Me
  6. Number One Mistake

  7. Proprietary and Confidential Do You Even Have a Problem?

  8. Common Causes of Slowdowns

  9. Proprietary and Confidential • Datastore • Doesn’t matter if it’s

    PostgreSQL, MySQL, Oracle, MongoDB, CouchDB, or MSSQL • External Resources • APIs, Filesystems, Network Sockets, External Processes • Bad Code • The only great code, is code that never has to run. Everything else, is just good code. Common Causes of Slowdowns
  10. The Performance Loop

  11. Proprietary and Confidential The Performance Loop

  12. Profiling

  13. Proprietary and Confidential • Profiling Records Relative Speed + Memory

    Usage + # of calls per function + Call graph • The act of profiling affects the speed (the outcome) of the code (just like quantum physics!) • Benchmarking Tests Actual Speed • What your users actually see Benchmarking Vs Profiling
  14. When Should I Profile My Code?

  15. Do I Have a Problem?

  16. Proprietary and Confidential • The #1 issue with performance tuning,

    is assuming you even have a problem. • Premature Optimization is a waste of time. • Determine desired performance (e.g. 100 concurrent users with less than 1s response times). Benchmark on production hardware. Do you even have a problem? How big? Do I Have a Problem?
  17. Choosing a Profiler

  18. Active Profilers

  19. Proprietary and Confidential • Development Only • Enabled/Activated by the

    Developer • Gather more information than passive profilers • Negatively impacts performance Active Profilers
  20. Passive Profilers

  21. Proprietary and Confidential • Minimal impact on performance • Gathers

    enough information to diagnose performance issues • Can be used in production Passive Profilers http://adw0rd.com/media/ 2010/04/xhprof.jpg
  22. Xhprof + Xhgui

  23. Installing Xhprof

  24. Proprietary and Confidential $ pecl install xhprof-beta // php.ini (or

    similar) [xhprof]
 extension=xhprof.so Installing Xhprof
  25. Installing Xhgui

  26. Proprietary and Confidential $ cd /var/www $ git clone https://github.com/perftools/xhgui.git

    $ cd xhgui $ php install.php # runs composer install & checks permissions Installing Xhgui
  27. Proprietary and Confidential • Default config found in: 
 /path/to/xhgui/config/config.default.php

    • Defaults to using mongodb on localhost without authentication Xhgui Configuration
  28. Alternative Configurations

  29. Proprietary and Confidential 'db.host' => ‘mongodb://mongo.host:27017', 'db.db' => 'xhprof',
 'db.options'

    => array(
 'username' => DB_USERNAME,
 'password' => DB_PASSWORD,
 ), Mongodb Configuration
  30. Proprietary and Confidential Configuration: 'save.handler' = 'file', 'save.handler.filename' => 


    '/path/to/xhgui/xhprof-' .uniqid("", true). '.dat' Load it into Xhgui: $ php 
 /path/to/xhgui/external/import.php 
 /path/to/file.dat Saving to File
  31. Web Server

  32. Proprietary and Confidential Nginx/Apache • Setup a virtual host as

    you would for any other PHP app • Document Root: /path/to/xhgui/webroot CLI Server $ cd /path/to/xhgui $ php -S 0:8080 -t webroot/ Web Server
  33. Using Xhprof

  34. Proprietary and Confidential • Use auto_prepend_file to include xhgui/external/header.php CLI

    Server $ php -dauto_prepend_file=/path/to/xhgui/external/ header.php -S 0.0.0.0:8080
 Nginx fastcgi_param PHP_VALUE 
 "auto_prepend_file=/path/to/xhgui/external/header.php"; Apache php_admin_value auto_prepend_file
 "/path/to/xhgui/external/header.php Using Xhgui
  35. Proprietary and Confidential • In xhgui/config/config.default.php
 'profiler.enable' => function() {

    return rand(0, 100) === 42; // ~1:100 Requests }, 'profiler.enable' => function() { return rand(0, 10) === 4; // ~1:10 Requests }, 'profiler.enable' => function() { return true; // Always }, Enabling the Profiler
  36. Proprietary and Confidential 'profiler.simple_url' => function($url) { return preg_replace('/\=\d+/', '',

    $url); } URL Simplification
  37. Proprietary and Confidential // Replace all numbers, and query params

    with XXX 'profiler.simple_url' => function($url) { $url = preg_replace("/[0-9]+/", "XXX", $url);
 $qs = parse_url($url, PHP_URL_QUERY); if ($qs) { $parts = array(); parse_str($qs, $parts); $v = array_pad(array(), sizeof($parts), "XXX"); $normalized = array_combine(array_keys($parts), $v); $replace = http_build_query($normalized); $url = str_replace($qs, $replace, $url); } return $url; }, URL Simplification (Cont.)
  38. Proprietary and Confidential Run your code. That’s it.

  39. Proprietary and Confidential Xhgui In-Depth

  40. Proprietary and Confidential Glossary

  41. Proprietary and Confidential Exclusive vs Inclusive

  42. Proprietary and Confidential • Exclusive is just the current scope

    (e.g. a function), excluding any other code it calls • Inclusive is the current scope and any code it calls Exclusive vs Inclusive
  43. Proprietary and Confidential • Call Count • How many times

    the function is called • [Inclusive] Wall Time (wt) • How long a function took in real time • [Inclusive] CPU Usage/CPU Time (cpu) • How much time the CPU spent running the function • [Inclusive] Memory Usage (mu) • How much memory is currently being used by the function • [Inclusive] Peak Memory Usage (pmu) • The peak memory usage used by the function Glossary
  44. Proprietary and Confidential • Exclusive Wall Time (ewt) • Exclusive

    CPU Time (ecpu) • Exclusive Memory Usage (emu) • Exclusive Peak Memory Usage (epmu) Exclusive
  45. Proprietary and Confidential (Demo)

  46. Proprietary and Confidential

  47. Proprietary and Confidential

  48. Proprietary and Confidential • Recent — The most recent runs

    (paged) • Longest wall time — Order by the slowest runs based on actual (wall) clock time • Most CPU — Order by the most CPU time • Most Memory — Order by the most memory usage • Custom View — Perform custom queries against the mongo DB • Watch Functions — Mark functions that should appear at the top of the run for review • Waterfall — An experimental view for reviewing how concurrent requests impact each other
  49. Proprietary and Confidential

  50. Proprietary and Confidential

  51. Proprietary and Confidential Reviewing Profile Data

  52. Proprietary and Confidential

  53. Proprietary and Confidential

  54. Proprietary and Confidential

  55. Proprietary and Confidential

  56. Proprietary and Confidential

  57. Proprietary and Confidential

  58. Proprietary and Confidential

  59. Proprietary and Confidential

  60. Proprietary and Confidential Function Details

  61. Proprietary and Confidential

  62. Proprietary and Confidential

  63. Proprietary and Confidential Trends

  64. Proprietary and Confidential Trends Over Time

  65. Proprietary and Confidential

  66. Proprietary and Confidential

  67. Proprietary and Confidential

  68. Proprietary and Confidential

  69. Proprietary and Confidential

  70. Proprietary and Confidential

  71. Proprietary and Confidential

  72. Proprietary and Confidential

  73. Proprietary and Confidential

  74. Proprietary and Confidential

  75. Proprietary and Confidential

  76. Proprietary and Confidential

  77. Proprietary and Confidential Comparing Data

  78. Proprietary and Confidential

  79. Proprietary and Confidential

  80. Proprietary and Confidential

  81. Proprietary and Confidential

  82. Proprietary and Confidential

  83. Proprietary and Confidential

  84. Proprietary and Confidential

  85. Proprietary and Confidential

  86. Proprietary and Confidential

  87. Proprietary and Confidential

  88. Proprietary and Confidential

  89. Proprietary and Confidential

  90. Proprietary and Confidential Watch Functions

  91. Proprietary and Confidential

  92. Proprietary and Confidential

  93. Proprietary and Confidential • mysql_(.*) for ext/mysql • mysqli(.*) for

    ext/mysqli • pdo(.*) for PDO (which will work for all PDO-based database interactions) Watch all MySQL DB Activity
  94. Proprietary and Confidential

  95. Proprietary and Confidential Callgraph

  96. Proprietary and Confidential

  97. Proprietary and Confidential

  98. Proprietary and Confidential

  99. None
  100. Proprietary and Confidential Feedback & Questions: Feedback: https://joind.in/
 Twitter: @dshafik

    Email: davey@engineyard.com Slides: http://daveyshafik.com/slides 13110 Xhprof: http://pecl.php.net Xhgui: http://github.com/perftools/xhgui Resources