Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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

PHP 7.0 is already history. But do you know how to take full advantage of it? If the engine is faster on all operations in general, some of them are particularly optimized. With PHP 5, you may have taken some habits that are no longer topical to write faster code? I propose to review with you the various optimization techniques implemented in Symfony, which make the v4 the fastest ever published. This will be an opportunity to twist the puzzle around a few preconceived ideas, and give you a few more for the day when you'll try to squeeze the last few milliseconds out of this intensive loop. Benchmark in support of course.

Nicolas Grekas

April 12, 2018
Tweet

More Decks by Nicolas Grekas

Other Decks in Technology

Transcript

  1. • Born in 1995 – v7 end of 2016 •

    870,000 C lines of code • Distributed leadership The PHP engine
  2. • Since 2011 – v4 end of 2017 • PHP

    ^7.1 • 98 packages • 1.5B downloads Symfony
  3. • Code infrastructure since Drupal 8 • Now at Symfony

    v3.4 • Deprecation policy and code • Time-based releasing process Symfony in Drupal
  4. 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
  5. First steps are immutable index.php Lexing + parsing AST opcodes

    Compiling Executing result Shared memory* *append-only
  6. Compile time optimizations AST opcodes Compiling Shared memory • Compile-time

    evaluation 'foo'."bar" • Dead-code elimination if (false) {…}
  7. 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
  8. 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
  9. • 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
  10. 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()
  11. Runtime-resolved identifiers are cached in the (local) opcode array Don’t

    « \ » all function calls Stick to the short list
  12. Let’s split the container in one file per service PHP

    7 is slow… at compiling https://github.com/symfony/symfony/pull/23678
  13. • 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
  14. • 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
  15. • gc_collect_cycles() autotriggered past 10k objects • gc_mem_caches() PHP7 memory

    manager is lazy • Much improved in PHP 7.3 PHP garbage collector
  16. • 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
  17. • 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
  18. Conclusion • Wow PHP 7 • Source ideas in PHP’s

    C • Use only in tight loops • Never stop measuring
  19. 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
  20. 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