Slide 1

Slide 1 text

Profiling 101: How to profile a PHP 7 application Tilburg PHP Meetup 2019 - 02 - 06 Camilo Sperberg / @unreal4u

Slide 2

Slide 2 text

A little favor… !2 Let me know if my "ehmm" tag becomes too annoying

Slide 3

Slide 3 text

Main index !3 What is profiling? When to profile? What to profile? How to profile? Precautions and general learnings Live failuredemo!

Slide 4

Slide 4 text

What is profiling? (…) profiling is a form of dynamic program analysis that measures (…) memory or time complexity of a program, the usage of particular instructions, or the frequency and duration of function calls !4 https://en.wikipedia.org/wiki/Profiling_(computer_programming)

Slide 5

Slide 5 text

What is profiling? Basically it allows you to understand what code affects the actual speed of your application !5

Slide 6

Slide 6 text

MAGIC GIF !6

Slide 7

Slide 7 text

Profiling and debugging !7 Profiling Measures an application on an analysis tool (profiler) Puts the focus on performance Mainly: functions call times and count, memory usage, cpu load, and resource usage Debugging Process of finding and fixing bugs in a computer program Puts the focus on finding a certain piece of code that misbehaves

Slide 8

Slide 8 text

Profiling and debugging !8 Profiling Debugging Process of finding and fixing bugs in a computer program Puts the focus on finding a certain piece of code that misbehaves

Slide 9

Slide 9 text

When to profile? !9 1. When you suspect or know a certain part of the application is slow 2. If you are curious about the flow of an application

Slide 10

Slide 10 text

The Do’s of profiling !10 ‣ Try to analyse small pieces of code ‣ Reproduce the same scenario as it would on production ‣ Try to optimise the code that has the most impact ‣ In depth analysis: debug, debug, debug ‣ Run profiler multiple times: opcache, I/O and other external factors will influence the results

Slide 11

Slide 11 text

The Don’ts of profiling !11 ‣ When you are done, do NOT forget to turn profiler off

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

The Don’ts of profiling !13 ‣ When you are done, do NOT forget to turn profiler off ‣ With Xdebug, do NOT profile on production ‣ Strong influence of the observer effect

Slide 14

Slide 14 text

Profilers !14 Xdebug XHProf blackfire.io phpspy

Slide 15

Slide 15 text

How to profile !15 ‣ Install Xdebug ‣ Enable the profiler: xdebug.profiler_enable = On xdebug.profiler_output_dir = "/var/www/cachegrind" xdebug.profiler_output_name = callgrind.%s.%p-%r.xt xdebug.profiler_enable_trigger = 0 ‣ Restart the web server (Must. Not. Forget.)

Slide 16

Slide 16 text

How to analyse profile data !16 ‣ Multiple options, but we’ll cover qcachegrind in this talk ‣ PHPStorm sorta kinda implements-ish a profile reader

Slide 17

Slide 17 text

Main areas of concern !17 SQL Queries API’s Filesystem calls Slow code

Slide 18

Slide 18 text

!18

Slide 19

Slide 19 text

Demo time!!! !19

Slide 20

Slide 20 text

Example code #1 !20 $longString = 'Hello world, this shall be a very interesting way of '; $longString .= 'counting stuff, but totally the wrong way!'; for ($i = 0; $i < strlen($longString); $i++) { printf('Letter: %s' . PHP_EOL, substr($longString, $i, 1)); } printf('We\'re done!' . PHP_EOL); die();

Slide 21

Slide 21 text

Example code #1 - Optimised !21 $longString = 'Hello world, this shall be a very interesting way of '; $longString .= 'counting stuff, but totally the wrong way!'; $longStringLength = strlen($longString); for ($i = 0; $i < $longStringLength; $i++) { echo 'Letter: ' . $longString[$i] . PHP_EOL; } echo 'We\'re done!' . PHP_EOL; die();

Slide 22

Slide 22 text

Example code #2 !22 declare(strict_types=1); chdir(__DIR__); const MAX_ITERATIONS = 50; const KEYSPACE = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; function generateRandomString(int $length, $fileHandler): string { $pieces = []; $max = mb_strlen(KEYSPACE, '8bit') - 1; for ($i = 0; $i < $length; ++$i) { $pieces[] = KEYSPACE[random_int(0, $max)]; } fwrite($fileHandler, implode('', $pieces) . PHP_EOL); return implode('', $pieces); } $fileHandler = fopen('output.txt', 'ab+'); for ($i = 0; $i < MAX_ITERATIONS; $i++) { $generatedString = generateRandomString(random_int(12, 200), $fileHandler); printf('String #%3d is %d bytes long' . PHP_EOL, $i, strlen($generatedString)); } fclose($fileHandler); unlink('output.txt');

Slide 23

Slide 23 text

Example code #2 - Optimised !23 declare(strict_types=1); chdir(__DIR__); const MAX_ITERATIONS = 50; const KEYSPACE = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; function generateRandomString(int $length, $fileHandler): string { $entropySpace = str_repeat(KEYSPACE, (int)ceil($length / strlen(KEYSPACE))); $generatedString = substr(str_shuffle($entropySpace), 0, $length); fwrite($fileHandler, $generatedString . PHP_EOL); return $generatedString; } $fileHandler = fopen('output.txt', 'ab+'); for ($i = 0; $i < MAX_ITERATIONS; $i++) { $generatedString = generateRandomString(mt_rand(12, 200), $fileHandler); printf('String #%3d is %d bytes long' . PHP_EOL, $i, strlen($generatedString)); } fclose($fileHandler); unlink('output.txt');

Slide 24

Slide 24 text

!24 Finally: Who am I? Want to know more? My name is Camilo Sperberg Tweet me @unreal4u Email [email protected] or telegram.me/unreal4u

Slide 25

Slide 25 text

Finally: Who am I? ‣ Blog: http://blog.unreal4u.com/ (Spanish) ‣ Slides will be ready to be downloaded on: ‣ https://speakerdeck.com/unreal4u !25

Slide 26

Slide 26 text

Thanks! !26