EIN STALL VOLLERTRÜFFELSCHWEINE(PHP)-Profiling-Tools im ÜberblickRené Bruns - TNG Big Techday
ÜBER MICH                        René Bruns               Entwickler seit 2001               seit 2009 bei Travian Games...
UND WER SEID IHR?                    3
UND WER SEID IHR?Entwickler?                    3
UND WER SEID IHR?Entwickler?              Systemadministratoren?                                       3
UND WER SEID IHR?Entwickler?              Systemadministratoren?                                       QA?                ...
UND WER SEID IHR?Entwickler?              Systemadministratoren? C*O?                                  QA?                ...
UND WER SEID IHR?Entwickler?                            Projektmanager?              Systemadministratoren? C*O?          ...
PROFILING?             4
PROFILING?ProfilerEs gibt unterschiedliche Problembereiche in derSoftwareentwicklung, die durch ineffiziente Programmierun...
AUSGANGSSITUATION               SLOW!!11!                           6
PROFILING FRÜHER(?)class Main{    public static function run() {        $otherClass = new OtherClass();        $otherClass...
PROFILING FRÜHER(?)class Main{    public static function run() {        $start = microtime(true);        printf ("Before O...
PROFILING FRÜHER(?)class Main{    public static function run() {        $start = microtime(true);        printf ("Before O...
PROFILING HEUTE   Viele verschiedene Fehlerquellen     Browser     Frontend     Backend     Datenbank     Services ...
SCHRITT 1: MELDUNG ÜBERPRÜFEN                      He‘s                      dead,                      Jim!              ...
SCHRITT 2: URSACHE EINKREISEN                Browser                                11
SCHRITT 2: URSACHE EINKREISEN                Browser                Frontend                                11
SCHRITT 2: URSACHE EINKREISEN                Browser                Frontend                Backend                       ...
SCHRITT 2: URSACHE EINKREISEN                Browser                Frontend                Backend                  DB   ...
BROWSER   Langsamer JS-Code   Zu hoher Speicherverbrauch   Zu viele CSS-Selektoren   Langsame Ladezeiten     Zu viele...
GOOGLE CHROME                13
GOOGLE CHROME                14
GOOGLE CHROME                15
GOOGLE CHROME                16
GOOGLE CHROME                17
GOOGLE CHROME                17
GOOGLE CHROME                18
GOOGLE CHROME                18
GOOGLE CHROME                19
GOOGLE CHROME                19
FRONTEND / BACKEND   Unnötige Schreib- / Lesezugriffe in Schleifen   Log-Ausgaben   Schleifen sind unnötig geschachtelt...
XDEBUG   PHP Extension by Derick Rethans   Kann per INI-Direktive aktiviert werden   breites Einsatzspektrum     Debug...
XDEBUG         22
XDEBUG$ php -d xdebug.profiler_enable=1 -d xdebug.profiler_output_dir=. Main.php..........                                ...
XDEBUG$ php -d xdebug.profiler_enable=1 -d xdebug.profiler_output_dir=. Main.php..........$ ls -l ca*-rwxrwxrwx 1 rene sta...
XDEBUG$ php -d xdebug.profiler_enable=1 -d xdebug.profiler_output_dir=. Main.php..........$ ls -l ca*-rwxrwxrwx 1 rene sta...
XDEBUG   Cachegrind-Files können via KCachegrind, WinCachegrind, WebGrind oder PhpStorm-IDE    ausgewertet werden.   Bsp...
XDEBUG   Cachegrind-Files können via KCachegrind, WinCachegrind, WebGrind oder PhpStorm-IDE    ausgewertet werden.   Bsp...
XDEBUG         25
XHPROF   PHP Extension by Facebook   Kann codeseitig aktiviert werden   Profiler only   sehr schlanker Footprint, dahe...
XHPROFheader.php:include_once /usr/lib/php/pear/xhprof_lib/utils/xhprof_lib.php;include_once /usr/lib/php/pear/xhprof_lib/...
XHPROF$ php -d auto_append_fileo_prepend_file="header.php" -d auto_append_file="footer.php" Main.php..........http://local...
XHPROF$ php -d auto_append_fileo_prepend_file="header.php" -d auto_append_file="footer.php" Main.php..........http://local...
XHPROF         29
XHPROF         30
XHPROF         30
DATENBANK   Unnötige Daten geladen   Kein/falscher Index benutzt   Daten werden nach der Abfrage noch sortiert   Langs...
DB - EXPLAINselect LastName, FirstName, sum(UnitPrice * Quantity) from employees e inner joinorders o on e.EmployeeID = o....
DB - EXPLAINselect LastName, FirstName, sum(UnitPrice * Quantity) from employees e inner joinorders o on e.EmployeeID = o....
DB - EXPLAINselect LastName, FirstName, sum(UnitPrice * Quantity) from employees e inner joinorders o on e.EmployeeID = o....
SCHRITT 3: ERFOLG PRÜFEN   Hat die Optimierung etwas gebracht?   Vorher-Nachher-Check   Lasttests   Tools      Apache...
APACHE BENCHMARK (AB)$ ab -n 100 -c 10 http://localhost/~rene/talk/Main.phpThis is ApacheBench, Version 2.3 <$Revision: 65...
APACHE BENCHMARK (AB)$ ab -n 100 -c 10 http://localhost/~rene/talk/Main.phpThis is ApacheBench, Version 2.3 <$Revision: 65...
APACHE JMETER   verteilte Lasttests   Java-Programm   Client-Server-Architektur   Testen von      HTTP/S      SOAP  ...
JMETER - TESTPLAN ERSTELLEN   Manuell oder per HTTP Proxy Server                                         36
JMETER - TESTPLAN ERSTELLEN   Manuell oder per HTTP Proxy Server                                         37
JMETER - TESTPLAN ERSTELLEN   Manuell oder per HTTP Proxy Server                                         37
JMETER - TESTPLAN ERSTELLEN   Manuell oder per HTTP Proxy Server                                         37
JMETER - USER EINLOGGEN                          38
JMETER - USER EINLOGGEN                          39
JMETER - USER EINLOGGEN                          39
JMETER - USER EINLOGGEN                          39
JMETER - USER EINLOGGEN                          39
JMETER - PARALLELE ZUGRIFFE                              40
JMETER - PARALLELE ZUGRIFFE                              41
JMETER - BERICHTE                    42
LINKLISTE  Google Chrome: https://www.google.com/chrome  Chrome DevTools: https://developers.google.com/chrome-   develo...
FRAGEN?GERNE AUCH SPÄTER:MAIL: R.BRUNS@TRAVIANGAMES.COMTWITTER: @RENEBRUNS
Upcoming SlideShare
Loading in …5
×

Ein Stall voller Trüffelschweine - (PHP-)Profiling-Tools im Überblick

8,036 views

Published on

Published in: Technology
  • Be the first to comment

Ein Stall voller Trüffelschweine - (PHP-)Profiling-Tools im Überblick

  1. 1. EIN STALL VOLLERTRÜFFELSCHWEINE(PHP)-Profiling-Tools im ÜberblickRené Bruns - TNG Big Techday
  2. 2. ÜBER MICH René Bruns  Entwickler seit 2001  seit 2009 bei Travian Games  seit 2011 Technical Director 2
  3. 3. UND WER SEID IHR? 3
  4. 4. UND WER SEID IHR?Entwickler? 3
  5. 5. UND WER SEID IHR?Entwickler? Systemadministratoren? 3
  6. 6. UND WER SEID IHR?Entwickler? Systemadministratoren? QA? 3
  7. 7. UND WER SEID IHR?Entwickler? Systemadministratoren? C*O? QA? 3
  8. 8. UND WER SEID IHR?Entwickler? Projektmanager? Systemadministratoren? C*O? QA? 3
  9. 9. PROFILING? 4
  10. 10. PROFILING?ProfilerEs gibt unterschiedliche Problembereiche in derSoftwareentwicklung, die durch ineffiziente Programmierungausgelöst werden. Ein Profiler hilft dem Entwickler durchAnalyse und Vergleich von laufenden Programmen dieProblembereiche aufzudecken.http://de.wikipedia.org/wiki/Profiler_(Programmierung) 5
  11. 11. AUSGANGSSITUATION SLOW!!11! 6
  12. 12. PROFILING FRÜHER(?)class Main{ public static function run() { $otherClass = new OtherClass(); $otherClass->doNothingImportant(); $dummy = new SlowClass(); $dummy->slowFunction(10); }}Main::run(); 7
  13. 13. PROFILING FRÜHER(?)class Main{ public static function run() { $start = microtime(true); printf ("Before OC: %f" . PHP_EOL, microtime(true) - $start); $otherClass = new OtherClass(); $otherClass->doNothingImportant(); printf ("After OC: %f" . PHP_EOL, microtime(true) - $start); printf ("Before SC: %f" . PHP_EOL, microtime(true) - $start); $dummy = new SlowClass(); $dummy->slowFunction(10); printf ("After SC: %f" . PHP_EOL, microtime(true) - $start); }}Main::run(); 8
  14. 14. PROFILING FRÜHER(?)class Main{ public static function run() { $start = microtime(true); printf ("Before OC: %f" . PHP_EOL, microtime(true) - $start); $otherClass = new OtherClass(); $otherClass->doNothingImportant(); printf ("After OC: %f" . PHP_EOL, microtime(true) - $start); printf ("Before SC: %f" . PHP_EOL, microtime(true) - $start); $dummy = new SlowClass(); $dummy->slowFunction(10); printf ("After SC: %f" . PHP_EOL, microtime(true) - $start); }} $ php Main.php Before OC: 0.000625Main::run(); After OC: 0.004919 Before SC: 0.005099 .......... After SC: 10.013932 8
  15. 15. PROFILING HEUTE Viele verschiedene Fehlerquellen  Browser  Frontend  Backend  Datenbank  Services Schwachstelle suchen Vom Groben in‘s Feine 9
  16. 16. SCHRITT 1: MELDUNG ÜBERPRÜFEN He‘s dead, Jim! 10
  17. 17. SCHRITT 2: URSACHE EINKREISEN Browser 11
  18. 18. SCHRITT 2: URSACHE EINKREISEN Browser Frontend 11
  19. 19. SCHRITT 2: URSACHE EINKREISEN Browser Frontend Backend 11
  20. 20. SCHRITT 2: URSACHE EINKREISEN Browser Frontend Backend DB 11
  21. 21. BROWSER Langsamer JS-Code Zu hoher Speicherverbrauch Zu viele CSS-Selektoren Langsame Ladezeiten  Zu viele parallele Downloads  Offen gehaltene Verbindungen  Netzwerk  Internet Antwort vom Server zu langsam -> Backend 12
  22. 22. GOOGLE CHROME 13
  23. 23. GOOGLE CHROME 14
  24. 24. GOOGLE CHROME 15
  25. 25. GOOGLE CHROME 16
  26. 26. GOOGLE CHROME 17
  27. 27. GOOGLE CHROME 17
  28. 28. GOOGLE CHROME 18
  29. 29. GOOGLE CHROME 18
  30. 30. GOOGLE CHROME 19
  31. 31. GOOGLE CHROME 19
  32. 32. FRONTEND / BACKEND Unnötige Schreib- / Lesezugriffe in Schleifen Log-Ausgaben Schleifen sind unnötig geschachtelt Unnötig langsame Befehle benutzt  RegExp statt == Externer Service reagiert langsam Datenbankabfrage dauert zu lange --> DB 20
  33. 33. XDEBUG PHP Extension by Derick Rethans Kann per INI-Direktive aktiviert werden breites Einsatzspektrum  Debugger  Profiler  Tracer  StackTrace-Formatter  ... hoher Memory-/ CPU-/ IO-Footprint Niemals(!) dauerhaft im Produktivbetrieb verwenden 21
  34. 34. XDEBUG 22
  35. 35. XDEBUG$ php -d xdebug.profiler_enable=1 -d xdebug.profiler_output_dir=. Main.php.......... 22
  36. 36. XDEBUG$ php -d xdebug.profiler_enable=1 -d xdebug.profiler_output_dir=. Main.php..........$ ls -l ca*-rwxrwxrwx 1 rene staff 4461 11 Jun 13:53 cachegrind.out.69408 22
  37. 37. XDEBUG$ php -d xdebug.profiler_enable=1 -d xdebug.profiler_output_dir=. Main.php..........$ ls -l ca*-rwxrwxrwx 1 rene staff 4461 11 Jun 13:53 cachegrind.out.69408$ cat cachegrind.out.69408version: 1creator: xdebug 2.2.0cmd: /Volumes/TCDATA/Sourcen/git/ProfilingTalk/Main.phppart: 1positions: lineevents: Timefl=/Volumes/TCDATA/Sourcen/git/ProfilingTalk/OtherClass.phpfn=require_once::/Volumes/TCDATA/Sourcen/git/ProfilingTalk/OtherClass.php1 42fl=/Volumes/TCDATA/Sourcen/git/ProfilingTalk/SlowClass.phpfn=require_once::/Volumes/TCDATA/Sourcen/git/ProfilingTalk/SlowClass.php10 22
  38. 38. XDEBUG Cachegrind-Files können via KCachegrind, WinCachegrind, WebGrind oder PhpStorm-IDE ausgewertet werden. Bsp. PhpStorm: 23
  39. 39. XDEBUG Cachegrind-Files können via KCachegrind, WinCachegrind, WebGrind oder PhpStorm-IDE ausgewertet werden. Bsp. PhpStorm: 24
  40. 40. XDEBUG 25
  41. 41. XHPROF PHP Extension by Facebook Kann codeseitig aktiviert werden Profiler only sehr schlanker Footprint, daher auch im Livebetrieb einsetzbar (Monte Carlo-Algorithmus) 26
  42. 42. XHPROFheader.php:include_once /usr/lib/php/pear/xhprof_lib/utils/xhprof_lib.php;include_once /usr/lib/php/pear/xhprof_lib/utils/xhprof_runs.php;xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);footer.php:include_once /usr/lib/php/pear/xhprof_lib/utils/xhprof_lib.php;include_once /usr/lib/php/pear/xhprof_lib/utils/xhprof_runs.php;$xhprof_data = xhprof_disable();$xhprof_runs = new XHProfRuns_Default();$run_id = $xhprof_runs->save_run($xhprof_data, testrene);echo "http://localhost/~rene/xhprof_html/index.php?run={$run_id}&source=testrenen"; 27
  43. 43. XHPROF$ php -d auto_append_fileo_prepend_file="header.php" -d auto_append_file="footer.php" Main.php..........http://localhost/~rene/xhprof_html/index.php?run=4fd61a7e92aeb&source=testrene 28
  44. 44. XHPROF$ php -d auto_append_fileo_prepend_file="header.php" -d auto_append_file="footer.php" Main.php..........http://localhost/~rene/xhprof_html/index.php?run=4fd61a7e92aeb&source=testrene$ cat 4fd61a7e92aeb.testrenea:14:{s:23:"main()==>load::Main.php";a:5:{s:2:"ct";i:1;s:2:"wt";i:459;s:3:"cpu";i:1220;s:2:"mu";i:10408;s:3:"pmu";i:0;}s:43:"main()==>load::ProfilingTalk/OtherClass.php";a:5:{s:2:"ct";i:1;s:2:"wt";i:798;s:3:"cpu";i:113;s:2:"mu";i:6880;s:3:"pmu";i:0;}s:47:"main()==>run_init::ProfilingTalk/OtherClass.php";a:5:{s:2:"ct";i:1;s:2:"wt";i:14;s:3:"cpu";i:10;s:2:"mu";i:1104;s:3:"pmu";i:0;}s:42:"main()==>load::ProfilingTalk/SlowClass.php";a:5:{s:2:"ct";i:1;s:2:"wt";i:467;s:3:"cpu";i:87;s:2:"mu";i:9648;s:3:"pmu";i:0;}s:46:"main()==>run_init::ProfilingTalk/SlowClass.php";a:5:{s:2:"ct";i:1;s:2:"wt";i:9;s:3:"cpu";i:7;s:2:"mu";i:1104;s:3:"pmu";i:0;}s:36:"OtherClass::doNothingImportant==>pow";a:5:{s:2:"ct";i:1;s:2:"wt";i:1655;s:3:"cpu";i:926;s:2:"mu";i:1176;s:3:"pmu";i:0;}[...]} 28
  45. 45. XHPROF 29
  46. 46. XHPROF 30
  47. 47. XHPROF 30
  48. 48. DATENBANK Unnötige Daten geladen Kein/falscher Index benutzt Daten werden nach der Abfrage noch sortiert Langsame IOs Falsche Systemeinstellungen (Buffer Sizes, ...) 31
  49. 49. DB - EXPLAINselect LastName, FirstName, sum(UnitPrice * Quantity) from employees e inner joinorders o on e.EmployeeID = o.EmployeeID inner join "Order Details" od on o.OrderID= od.OrderID group by LastName, FirstName; 32
  50. 50. DB - EXPLAINselect LastName, FirstName, sum(UnitPrice * Quantity) from employees e inner joinorders o on e.EmployeeID = o.EmployeeID inner join "Order Details" od on o.OrderID= od.OrderID group by LastName, FirstName;sqlite> explain query plan [...];0|0|0|SCAN TABLE employees AS e (~1000000 rows)0|1|1|SEARCH TABLE orders AS o USING AUTOMATIC COVERING INDEX (EmployeeID=?) (~7 rows)0|2|2|SEARCH TABLE Order Details AS od USING INDEX sqlite_autoindex_Order Details_1(OrderID=?) (~10 rows)0|0|0|USE TEMP B-TREE FOR GROUP BY 32
  51. 51. DB - EXPLAINselect LastName, FirstName, sum(UnitPrice * Quantity) from employees e inner joinorders o on e.EmployeeID = o.EmployeeID inner join "Order Details" od on o.OrderID= od.OrderID group by LastName, FirstName;sqlite> explain query plan [...];0|0|0|SCAN TABLE employees AS e (~1000000 rows)0|1|1|SEARCH TABLE orders AS o USING AUTOMATIC COVERING INDEX (EmployeeID=?) (~7 rows)0|2|2|SEARCH TABLE Order Details AS od USING INDEX sqlite_autoindex_Order Details_1(OrderID=?) (~10 rows)0|0|0|USE TEMP B-TREE FOR GROUP BYsqlite> explain [...];0|Trace|0|0|0||00|1|SorterOpen|3|5|0|keyinfo(2,BINARY,BINARY)|00|2|Integer|0|7|0||00|3|Integer|0|6|0||00|4|Null|0|10|11||00|5|Gosub|9|74|0||00|6|Goto|0|81|0||00|7|OpenRead|0|120|0|3|00| 32
  52. 52. SCHRITT 3: ERFOLG PRÜFEN Hat die Optimierung etwas gebracht? Vorher-Nachher-Check Lasttests Tools  Apache Benchmark (AB)  JMeter 33
  53. 53. APACHE BENCHMARK (AB)$ ab -n 100 -c 10 http://localhost/~rene/talk/Main.phpThis is ApacheBench, Version 2.3 <$Revision: 655654 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking localhost (be patient).....doneServer Software: Apache/2.2.21Server Hostname: localhostServer Port: 80Document Path: /~rene/talk/Main.phpDocument Length: 11 bytesConcurrency Level: 10Time taken for tests: 56.692 secondsComplete requests: 100Failed requests: 0Write errors: 0Total transferred: 22300 bytesHTML transferred: 1100 bytesRequests per second: 1.76 [#/sec] (mean)Time per request: 5669.198 [ms] (mean)Time per request: 566.920 [ms] (mean, across all concurrent requests)Transfer rate: 0.38 [Kbytes/sec] receivedConnection Times (ms) min mean[+/-sd] median maxConnect: 0 3660 2329.9 5022 6356Processing: 0 1758 3060.0 0 11378Waiting: 0 1757 3059.9 0 11377Total: 5010 5417 1403.8 5030 11378Percentage of the requests served within a certain time (ms) 50% 5030 66% 5040 75% 5052 80% 5063 90% 6316 95% 11378 vorher 98% 11378 99% 11378 100% 11378 (longest request) 34
  54. 54. APACHE BENCHMARK (AB)$ ab -n 100 -c 10 http://localhost/~rene/talk/Main.phpThis is ApacheBench, Version 2.3 <$Revision: 655654 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/ $ ab -n 100 -c 10 http://localhost/~rene/talk/Main.phpBenchmarking localhost (be patient).....done This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/Server Software: Apache/2.2.21Server Hostname: localhost Benchmarking localhost (be patient).....doneServer Port: 80Document Path: /~rene/talk/Main.php Server Software: Apache/2.2.21Document Length: 11 bytes Server Hostname: localhost Server Port: 80Concurrency Level: 10Time taken for tests: 56.692 seconds Document Path: /~rene/talk/Main.phpComplete requests: 100 Document Length: 11 bytesFailed requests: 0Write errors: 0 Concurrency Level: 10Total transferred: 22300 bytes Time taken for tests: 5.395 secondsHTML transferred: 1100 bytes Complete requests: 100Requests per second: 1.76 [#/sec] (mean) Failed requests: 0Time per request: 5669.198 [ms] (mean) Write errors: 0Time per request: 566.920 [ms] (mean, across transferred: Total all concurrent requests) 22300 bytesTransfer rate: 0.38 [Kbytes/sec] received HTML transferred: 1100 bytes Requests per second: 18.54 [#/sec] (mean)Connection Times (ms) Time per request: 539.458 [ms] (mean) min mean[+/-sd] median max Time per request: 53.946 [ms] (mean, across all concurrent requests)Connect: 0 3660 2329.9 5022 6356 Transfer rate: 4.04 [Kbytes/sec] receivedProcessing: 0 1758 3060.0 0 11378Waiting: 0 1757 3059.9 0 11377 Connection Times (ms)Total: 5010 5417 1403.8 5030 11378 min mean[+/-sd] median max Connect: 0 395 217.3 531 577Percentage of the requests served within a certain time (ms) 0 142 214.4 Processing: 1 559 50% 5030 Waiting: 0 142 214.6 0 559 66% 5040 Total: 512 538 14.9 535 577 75% 5052 80% 5063 vorher Percentage of the requests served within a certain time (ms) 90% 6316 50% 535 95% 11378 66% 541 98% 11378 75% 553 nachher 99% 11378 80% 555 100% 11378 (longest request) 90% 559 95% 559 98% 566 99% 577 100% 577 (longest request) 34
  55. 55. APACHE JMETER verteilte Lasttests Java-Programm Client-Server-Architektur Testen von  HTTP/S  SOAP  DB‘s via JDBC  SMTP, POP3, IMAP  ... 35
  56. 56. JMETER - TESTPLAN ERSTELLEN Manuell oder per HTTP Proxy Server 36
  57. 57. JMETER - TESTPLAN ERSTELLEN Manuell oder per HTTP Proxy Server 37
  58. 58. JMETER - TESTPLAN ERSTELLEN Manuell oder per HTTP Proxy Server 37
  59. 59. JMETER - TESTPLAN ERSTELLEN Manuell oder per HTTP Proxy Server 37
  60. 60. JMETER - USER EINLOGGEN 38
  61. 61. JMETER - USER EINLOGGEN 39
  62. 62. JMETER - USER EINLOGGEN 39
  63. 63. JMETER - USER EINLOGGEN 39
  64. 64. JMETER - USER EINLOGGEN 39
  65. 65. JMETER - PARALLELE ZUGRIFFE 40
  66. 66. JMETER - PARALLELE ZUGRIFFE 41
  67. 67. JMETER - BERICHTE 42
  68. 68. LINKLISTE  Google Chrome: https://www.google.com/chrome  Chrome DevTools: https://developers.google.com/chrome- developer-tools/?hl=de  Xdebug: http://xdebug.org/  PHPStorm: http://www.jetbrains.com/phpstorm/  KCachegrind: http://kcachegrind.sourceforge.net  WinCacheGrind: http://sourceforge.net/projects/wincachegrind/  Webgrind: http://code.google.com/p/webgrind/  XHProf: http://php.net/xhprof  AB: http://httpd.apache.org/docs/2.0/programs/ab.html  Jmeter: http://jmeter.apache.org/ 43
  69. 69. FRAGEN?GERNE AUCH SPÄTER:MAIL: R.BRUNS@TRAVIANGAMES.COMTWITTER: @RENEBRUNS

×