Slide 1

Slide 1 text

Getting the most out of the PHP 7 engine - the example of

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Getting the most out of the PHP 7 engine - the example of

Slide 4

Slide 4 text

@nicolasgrekas

Slide 5

Slide 5 text

live.symfony.com

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

• Born in 1995 – v7 end of 2016 • 870,000 C lines of code • Distributed leadership The PHP engine

Slide 8

Slide 8 text

• Since 2011 – v4 end of 2017 • PHP ^7.1 • 98 packages • 1.5B downloads Symfony

Slide 9

Slide 9 text

• Code infrastructure since Drupal 8 • Now at Symfony v3.4 • Deprecation policy and code • Time-based releasing process Symfony in Drupal

Slide 10

Slide 10 text

blog.jpauli.tech nikic.github.io

Slide 11

Slide 11 text

Synchronous and parallel Master Child 1 Child 2 Child n index.php index.php index.php index.php index.php index.php PHP’s memory manager insulates each scripts

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

spl_autoload_register( Composer\Autoload\ClassLoader) Implement more in userland

Slide 14

Slide 14 text

Cache

Slide 15

Slide 15 text

Persistent memory pools Master Child n index.php index.php index.php Process memory Shared memory

Slide 16

Slide 16 text

• realpath_cache_size=1M • clearstatcache() • Compiled RegExps • OPcache What does PHP cache?

Slide 17

Slide 17 text

OPcache?

Slide 18

Slide 18 text

Steps to execute a script index.php Lexing + parsing AST opcodes Compiling Executing result

Slide 19

Slide 19 text

First steps are immutable index.php Lexing + parsing AST opcodes Compiling Executing result Shared memory* *append-only

Slide 20

Slide 20 text

Compile time optimizations AST opcodes Compiling Shared memory • Compile-time evaluation 'foo'."bar" • Dead-code elimination if (false) {…}

Slide 21

Slide 21 text

Compile time optimizations AST opcodes Compiling Shared memory • Compile-time evaluation 'foo'."bar" • Dead-code elimination if (false) {…} • Interned strings "foobar" len=6 hash=Ox1234 • Immutable arrays [123, ["ab" => 34]] len=2 len=1

Slide 22

Slide 22 text

Compile time optimizations AST opcodes Compiling Shared memory • Compile-time evaluation 'foo'."bar" • Dead-code elimination if (false) {…} • Interned strings "foobar" len=6 hash=Ox1234 • Immutable arrays [123, ["ab" => 34]] len=2 len=1

Slide 23

Slide 23 text

• Works for constants 'cli' === PHP_SAPI • Works for some native functions 1 === count([123]) • Needs fully-qualified identifiers namespace App; \count([123]); Compile time evaluation

Slide 24

Slide 24 text

namespace App; is_array($a); \is_array($a); Compile time inlining https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues/3048 strlen(), is_{type}(), {type}val() casts, defined(), chr(), ord(), call_user_function(), call_user_function_array(), get_class(), get_called_class(), gettype(), count(), in_array(), array_slice(), func_num_args(), func_get_args(), function_exists(), is_callable(), extension_loaded(), constant(), dirname()

Slide 25

Slide 25 text

Compile time inlining https://github.com/symfony/symfony/pull/25854

Slide 26

Slide 26 text

Runtime-resolved identifiers are cached in the (local) opcode array Don’t « \ » all function calls Stick to the short list

Slide 27

Slide 27 text

Let’s split the container in one file per service PHP 7 is slow… at compiling https://github.com/symfony/symfony/pull/23678

Slide 28

Slide 28 text

• Loading opcodes is really fast • Still takes time and memory • « require » is also really fast opcodes move from shared memory to process’ https://github.com/symfony/symfony/pull/23678

Slide 29

Slide 29 text

Interned strings and immutable arrays stay in shared memory Mind opcache.interned_strings_buffer

Slide 30

Slide 30 text

Leveraging shared memory https://blog.blackfire.io/speeding-up-autoloading-on-php-5-6-7-0-for-everyone.html https://blog.blackfire.io/php-7-performance-improvements-immutable-arrays.html

Slide 31

Slide 31 text

• Shared memory is read-only $a = […]; $a[0] = 123; • Duplication happens on « write » $a = "abc"; $b = $a; $b .= "ghi"; (by the way, scalars are free, and declared properties make objects very compact) https://blog.blackfire.io/php-7-performance-improvements-ints-floats-free.html ❤ Copy-on-write

Slide 32

Slide 32 text

• AbstractRecursivePass • ClassLoader • VarCloner $cache[$k][$v] = [$k => $v]; Not triggering copy-on-write

Slide 33

Slide 33 text

What else can be slow?

Slide 34

Slide 34 text

Bypassing the autoloader

Slide 35

Slide 35 text

• gc_collect_cycles() autotriggered past 10k objects • gc_mem_caches() PHP7 memory manager is lazy • Much improved in PHP 7.3 PHP garbage collector

Slide 36

Slide 36 text

• Coalesce operator A ?? B vs isset(A) ? A : B https://github.com/symfony/symfony/pull/26161 • Ropes for encapsed strings "$a and $b" vs $a." and ".$b https://blog.blackfire.io/php-7-performance-improvements-encapsed-strings-optimization.html • Packed arrays (incrementing keys only) https://blog.blackfire.io/php-7-performance-improvements-packed-arrays.html • Class constants can be slow https://github.com/symfony/symfony/pull/25474 - https://github.com/twigphp/Twig/pull/2636 More goodies

Slide 37

Slide 37 text

• Reference mismatches are gone https://blog.blackfire.io/php-7-performance-improvements-references-mismatch.html • Copy-on-write is not triggered by (string)/(array) cast • Since PHP 7.2, « switch » statements use a hashmap • JIT is actively worked on for PHP 8 (no ETA) Even more goodies

Slide 38

Slide 38 text

http://www.phpbenchmarks.com/en/comparator/frameworks.html

Slide 39

Slide 39 text

https://rawgit.com/kocsismate/php-di-container-benchmarks/master/var/benchmark.html

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

Conclusion • Wow PHP 7 • Source ideas in PHP’s C • Use only in tight loops • Never stop measuring

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

Join us for contribution sprints Friday, April 13, 2018 9:00-18:00 Room: 103 Mentored Core sprint First time sprinter workshop General sprint #drupalsprint 9:00-12:00 Room: 101 9:00-18:00 Room: 104

Slide 44

Slide 44 text

What did you think? Locate this session at the DrupalCon Nashville website: http://nashville2018.drupal.org/schedule Take the Survey! https://www.surveymonkey.com/r/nashiville