Performances
considerations
with PHP 7
Hi
 Julien PAULI
 SensioLabs tech team (Blackfire - PHP)
 Programming with PHP since early 2000s
 Today working as Unix system programmer (C)
 PHP Internals programmer/contributor
 PHP 5.5 & 5.6 Release Manager
 @julienpauli
 Tech blog at http://jpauli.github.io
 jpauli@php.net
What we'll cover together
 PHP 7 new engine design
 What has changed inside PHP from PHP 5 ?
 PHP 7 new compiler
 Compiler optimizations
 PHP 7 new references mechanism
 PHP 7 new Hashtables (PHP arrays)
 PHP 7 new strings management
The PHP language
 Born in 1995
 Fully written using the C language
 Today
 822,000 C lines of code
 dozens of contributors around the world
PHP VERSIONS SURVEY
PHP code compilation
PHP 7 new compiler
 PHP 7 compiler is now based on an AST
 It has been fully rewritten, and can compute much
more things at compile time
 Every hash of every litteral string f.e
 Resolves every static/litteral expression
 Optimizes some function calls when result is known
at compile time
 defined(), strlen(), cufa(), is_{type}(), assert(), chr(), ord()
 Don't use namespaced calls but native_calls()
PHP 7 optimized compiled functions
namespace Foo;
class Bar
{
public function hello($str)
{
return "Hello" . strlen($str);
}
}
L7 #0 RECV 1 $str
L9 #1 INIT_NS_FCALL_BY_NAME "Foostrlen"
L9 #2 SEND_VAR_EX $str 1
L9 #3 DO_FCALL @0
L9 #4 CONCAT "Hello" @0 ~1
L9 #5 RETURN ~1
PHP 7 optimized compiled functions
namespace Foo;
class Bar
{
public function hello($str)
{
return "Hello" . strlen($str);
}
}
L7 #0 RECV 1 $str
L9 #1 STRLEN $str ~0
L9 #2 CONCAT "Hello" ~0 ~1
L9 #3 RETURN ~1
L10 #4 RETURN null
Namespaced function calls
 We have proven that the performance difference is
really tiny on real use cases.
namespace Foo;
class Bar
{
public function hello($str)
{
return "Hello" . strlen($str);
}
}
namespace Foo;
class Bar
{
public function hello($str)
{
return "Hello" . strlen($str);
}
}
VS
PHP 7 optimized compiled functions
$b = 'foo';
echo strlen($b);
L3 #0 ASSIGN $b "foo"
L5 #1 STRLEN $b ~1
L5 #2 ECHO ~1
echo strlen('foo');
L1 #0 ECHO 3
 Dynamic arg
 Static arg
PHP 7 new compiler
 PHP 7 compiler is usually slower than PHP 5's
 It optimizes more things
 It must walk an AST
 It is globally more complex
 It benefits from a better design
 It is hookable through PHP extensions
 Use OPCache to not suffer from compile time
PHP 7 compiler optim example, static arrays
 Arrays containg keys/vals that are static/litteral
 Such arrays are fully resolved at compile time
 They involve no runtime work at all
const FOO = ['bar', 'baz', 'foo', 34, [42, 'bar'=>'baz']];
Static arrays in PHP 5
 A lot of runtime is eaten to construct the same
array again and again
$a = ['bar', 'baz', 'foo', 34, [42, 'bar'=>'baz']];
3 0 E > INIT_ARRAY ~0 'bar'
1 ADD_ARRAY_ELEMENT ~0 'baz'
2 ADD_ARRAY_ELEMENT ~0 'foo'
3 ADD_ARRAY_ELEMENT ~0 34
4 INIT_ARRAY ~1 42
5 ADD_ARRAY_ELEMENT ~1 'baz', 'bar'
6 ADD_ARRAY_ELEMENT ~0 ~1
7 ASSIGN !0, ~0
Static arrays in PHP 7
 No runtime impact (but compile-time)
 You'd better use OPCache
$a = ['bar', 'baz', 'foo', 34, [42, 'bar'=>'baz']];
L3 #0 ASSIGN $a array(5)
PHP 7 new references mechanism
 In PHP 5, ref mismatching a function call triggered a
full zval copy the engine
 In PHP 7, the deep copy is postponed until COW
breakage
function foo($arg) { }
$a = 'foo';
$b = &$a;
foo($a); /* full copy of the argument */
PHP 7 new references mechanism
 In PHP 7, the deep copy is postponed until COW
breakage
 If no COW breakage, then no copy happens at all
function foo($arg) { $arg = 'bar'; } /* full copy of the variable */
$a = 'foo';
$b = &$a;
foo($a);
$a = ['foo', 42, ['bar' , new stdclass], 'baz'];
$b = &$a;
if (count($a) == 8) { /* no zval copy here */
}
PHP 7 optimizations
from internal
Optimizing CPU time
 Latency Numbers Every Programmer Should Know
 http://lwn.net/Articles/250967/
 http://www.eecs.berkeley.edu/~rcs/research/interactive
_latency.html
2016 numbers (may vary with chip)
---------------------------------------------------
L1 cache reference 1 ns
Branch mispredict 3 ns
L2 cache reference 4 ns 4x L1 cache
L3 cache reference 12 ns 3X L2 cache, 12x L1 cache
Main memory reference 100 ns 25x L2 cache, 100x L1 cache
SSD random read 16,000 ns
HDD random read(seek) 200,000,000 ns
Optimizing CPU cache efficiency
 If we can reduce payload size, the CPU will use its
caches more often
 CPU caches prefetch data on a "line" basis
 Improve data locality to improve cache efficiency
 https://software.intel.com/en-us/articles/optimize-data-
structures-and-memory-access-patterns-to-improve-
data-locality
 That means in C
 Reduce number of pointer indirections
 Stick data together (struct hacks, struct merges)
 Use smaller data sizes
PHP 7 cache efficiency
 If we can reduce payload size, the CPU will use its
caches more often
PHP 7.1.4-dev (debug)
128,883666 task-clock (msec)
9 context-switches
0 cpu-migrations
1 768 page-faults
340 930 642 cycles
810 206 077 instructions
100 639 058 branches
187 132 branch-misses
0,131802866 seconds time elapsed
PHP 5.6.31-dev (debug)
730,824226 task-clock (msec)
92 context-switches
1 cpu-migrations
74 691 page-faults
2 030 928 993 cycles
3 766 048 098 instructions
506 047 488 branches
356 931 branch-misses
0,773863158 seconds time elapsed
PHP 7 optimizations
 Every variable in PHP is coded on a zval struct
 This struct has been reorganized in PHP 7
 Narrowed / shrinked
 separated
 Hence, every variable usage in PHP 7 is more
optimized than in PHP 5
PHP 5 variables
value
refcount is_ref
type
gc_info
dval
str_val* str_len
hashtable*
object*
lval
ast*
zval
zval_value
...
...
HashTable
32 bytes
$a
8 bytes
zval *
XX bytes
 40 bytes + complex value size
 2 indirections
PHP 7 variables
value
type
internal_int
dval
zend_string*
object*
lval
...
zval
zval_value
...
...
HashTable
16 bytes
$a
zval
XX bytes
 16 bytes + complex value size
 1 indirection
hashtable*
gc_infos
refcount
infosflags
gc_infos
PHP 5 vs PHP 7 variable design
 zval container no longer stores GC infos
 No more need to heap allocate a zval *
 Very less pressure on the heap allocator
 GC infos stored into each complex types
 each complex type may now be shared
 In PHP 5, we had to share the zval containing them
 PHP 7 variables are much more CPU cache efficient
New Memory Allocator
 PHP 7 has a fully new heap memory allocator
 Zend Memory Manager
 It now uses several allocator pools
 Huge
 Medium
 Small
 ... for better efficiency
 Uses mmap(), no more libc's malloc() overhead
 May use Kernel Huge Pages if told to
 Better CPU TLB usage
PHP 7 new hashtables
PHP 7 hashtables
 It has been fully rewritten, and reworked
 Nothing to say from PHP userland POV
 Except perhaps for the packed array case
Packed arrays
Packed arrays
 If your keys are integer only (no string key)
 If your keys are constantly increasing
 No matter if they don't follow each other with +1
 Then you'll benefit from packed arrays optimization
 Packed arrays will reduce memory size compared
to "normal" array
 Reduction of (table_size - 2) * 4 bytes
 ~ 4Kb for a 1000 entry table
 May be noticeable for BIG arrays
Packed arrays example
const N = 1024 * 1023;
for ($i=0; $i<N; $i++) {
$tab[] = random_bytes(3);
}
echo memory_get_usage();
const N = 1024 * 1023;
for ($i=0; $i<N; $i++) {
$tab[] = random_bytes(3);
}
$tab['foo'] = 'bar';
echo memory_get_usage();
const N = 1024 * 1023;
for ($i=0; $i<N; $i++) {
$tab[] = random_bytes(3);
}
unset($tab[1000]);
$tab[1000] = 1000;
echo memory_get_usage();
~67Mb
~71Mb
~71Mb
Packed arrays conditions (recalled)
 Do NOT use string keys
 Always use increasing integer-based keys
 Contiguous or not is not important
 If using the compiler, keep keys into the interval [0-
table-size] , table-size being rounded to the upper
power of two
 For example, if you need lists , then you'll benefit
from this optimisation
HashTables in PHP 5
 Each element needs
 4 pointer indirections
 72 bytes for a bucket + 32 bytes for a zval
zval
zval *
HashTable
$a
zval *
HashTable*
bucket *
zval
64 bytes
72 bytesbucket
HashTables in PHP 7
 Each element needs
 2 pointer indirections
 32 bytes for a bucket
zval
bucket
HashTable
$a
zval
HashTable*
zval
56 bytes
32 bytes
bucket*
HashTables in PHP 7 : go further
 http://jpauli.github.io/2016/04/08/hashtables.html
Strings
$a = "bar";
String management
 In PHP 5, strings don't have their own structure
 String management is hard
 Leads to many strings duplication
 And thus many memory access
 In PHP 7, strings share the zend_string structure
 They are refcounted, thus shareable
 hashes are precomputed, often at compile time
 struct hack is used to compact memory
Strings in PHP
char * str
...
zval
gc_infos
int len
refcount is_ref zend_string *
...
zval
...
hash
gc_infos
char str[1]size_t len
...
zend_string
PHP 5 PHP 7
Strings in PHP 5
 $a = "foo";
3 0X00007FFFF7F8C708
foo0
Strings in PHP 7
 $a = "foo";
foo0
C struct hack
3
memory border
Strings tip
 Don't forget to use OPCache
 OPCache shares interned strings buffer between
processes
 Don't forget to size interned strings buffer
according to your needs
 opcache.interned_strings_buffer
interned string shared memory
PHP master process
PHP child #1 PHP child #2 PHP child #3
Encapsed strings
Encapsed string optimisation
 Encapsed string are double-quoted strings that get
parsed
 They need to be analyzed for variables
 PHP 5 used to reallocate the string at each step
$a = "foo and $b and $c";
3 0 E > ADD_STRING ~0 'foo+and+'
1 ADD_VAR ~0 ~0, !1
2 ADD_STRING ~0 ~0, '+and+'
3 ADD_VAR ~0 ~0, !2
4 ASSIGN !0, ~0
4 5 > RETURN 1
Encapsed string in PHP 5
$a = "foo and $b and $c";
3 0 E > ADD_STRING ~0 'foo+and+'
1 ADD_VAR ~0 ~0, !1
2 ADD_STRING ~0 ~0, '+and+'
3 ADD_VAR ~0 ~0, !2
4 ASSIGN !0, ~0
4 5 > RETURN 1
foo and
foo and b
foo and b and
foo and b and c
 Lot of pressure on the allocator
 Needs to find new chunk
 At every new allocation
 Browses through a free-chunk
linked-list
 Bad for performances
$b = 'b';
$c = 'c';
Encapsed string optimisation in PHP 7
 PHP 7 uses a "rope", and only reallocates memory
once, at the end
 https://en.wikipedia.org/wiki/Rope_(data_structure)
$a = "foo and $b and $c";
L3 #0 ROPE_INIT "foo and " ~1
L3 #1 ROPE_ADD ~1 $b ~1
L3 #2 ROPE_ADD ~1 " and " ~1
L3 #3 ROPE_END ~1 $c ~0
L3 #4 ASSIGN $a ~0
L3 #5 RETURN 1
Encapsed strings in PHP 7
$a = "foo and $b and $c";
L3 #0 ROPE_INIT "foo and " ~1
L3 #1 ROPE_ADD ~1 $b ~1
L3 #2 ROPE_ADD ~1 " and " ~1
L3 #3 ROPE_END ~1 $c ~0
L3 #4 ASSIGN $a ~0
L3 #5 RETURN 1
foo and
foo and b
foo and b and
foo and b and c
foo and b and c
INIT
ADD
ADD
ADD
END
 Keep every piece of string
as its own buffer
 Stack them
 At the end, merge them
as one operation
So ?
 So you'd better use encapsed strings
 Than concatenations
$a = "foo and $b and $c";
$a = 'foo and ' . $b . ' and ' . $c;
Future ?
Future of PHP
 PHP 7 branch keeps optimizing things
 PHP 7 branch keep preparing the massive JIT engine
move that should happen for PHP 8
 PHP 8 is not expected before 2020 at best
 Try at first to migrate to PHP 7 branch
 PHP 7.2 is on its way
 Nov - Dec 2017
 As usual, read wiki.php.net/rfc
 PHP 5.6 will die end of 2017 , and PHP 5 branch as well
Happy PHP 7 ing
Thank you for listening

Symfony live 2017_php7_performances

  • 1.
  • 2.
    Hi  Julien PAULI SensioLabs tech team (Blackfire - PHP)  Programming with PHP since early 2000s  Today working as Unix system programmer (C)  PHP Internals programmer/contributor  PHP 5.5 & 5.6 Release Manager  @julienpauli  Tech blog at http://jpauli.github.io  jpauli@php.net
  • 3.
    What we'll covertogether  PHP 7 new engine design  What has changed inside PHP from PHP 5 ?  PHP 7 new compiler  Compiler optimizations  PHP 7 new references mechanism  PHP 7 new Hashtables (PHP arrays)  PHP 7 new strings management
  • 4.
    The PHP language Born in 1995  Fully written using the C language  Today  822,000 C lines of code  dozens of contributors around the world
  • 5.
  • 6.
  • 7.
    PHP 7 newcompiler  PHP 7 compiler is now based on an AST  It has been fully rewritten, and can compute much more things at compile time  Every hash of every litteral string f.e  Resolves every static/litteral expression  Optimizes some function calls when result is known at compile time  defined(), strlen(), cufa(), is_{type}(), assert(), chr(), ord()  Don't use namespaced calls but native_calls()
  • 8.
    PHP 7 optimizedcompiled functions namespace Foo; class Bar { public function hello($str) { return "Hello" . strlen($str); } } L7 #0 RECV 1 $str L9 #1 INIT_NS_FCALL_BY_NAME "Foostrlen" L9 #2 SEND_VAR_EX $str 1 L9 #3 DO_FCALL @0 L9 #4 CONCAT "Hello" @0 ~1 L9 #5 RETURN ~1
  • 9.
    PHP 7 optimizedcompiled functions namespace Foo; class Bar { public function hello($str) { return "Hello" . strlen($str); } } L7 #0 RECV 1 $str L9 #1 STRLEN $str ~0 L9 #2 CONCAT "Hello" ~0 ~1 L9 #3 RETURN ~1 L10 #4 RETURN null
  • 10.
    Namespaced function calls We have proven that the performance difference is really tiny on real use cases. namespace Foo; class Bar { public function hello($str) { return "Hello" . strlen($str); } } namespace Foo; class Bar { public function hello($str) { return "Hello" . strlen($str); } } VS
  • 11.
    PHP 7 optimizedcompiled functions $b = 'foo'; echo strlen($b); L3 #0 ASSIGN $b "foo" L5 #1 STRLEN $b ~1 L5 #2 ECHO ~1 echo strlen('foo'); L1 #0 ECHO 3  Dynamic arg  Static arg
  • 12.
    PHP 7 newcompiler  PHP 7 compiler is usually slower than PHP 5's  It optimizes more things  It must walk an AST  It is globally more complex  It benefits from a better design  It is hookable through PHP extensions  Use OPCache to not suffer from compile time
  • 13.
    PHP 7 compileroptim example, static arrays  Arrays containg keys/vals that are static/litteral  Such arrays are fully resolved at compile time  They involve no runtime work at all const FOO = ['bar', 'baz', 'foo', 34, [42, 'bar'=>'baz']];
  • 14.
    Static arrays inPHP 5  A lot of runtime is eaten to construct the same array again and again $a = ['bar', 'baz', 'foo', 34, [42, 'bar'=>'baz']]; 3 0 E > INIT_ARRAY ~0 'bar' 1 ADD_ARRAY_ELEMENT ~0 'baz' 2 ADD_ARRAY_ELEMENT ~0 'foo' 3 ADD_ARRAY_ELEMENT ~0 34 4 INIT_ARRAY ~1 42 5 ADD_ARRAY_ELEMENT ~1 'baz', 'bar' 6 ADD_ARRAY_ELEMENT ~0 ~1 7 ASSIGN !0, ~0
  • 15.
    Static arrays inPHP 7  No runtime impact (but compile-time)  You'd better use OPCache $a = ['bar', 'baz', 'foo', 34, [42, 'bar'=>'baz']]; L3 #0 ASSIGN $a array(5)
  • 16.
    PHP 7 newreferences mechanism  In PHP 5, ref mismatching a function call triggered a full zval copy the engine  In PHP 7, the deep copy is postponed until COW breakage function foo($arg) { } $a = 'foo'; $b = &$a; foo($a); /* full copy of the argument */
  • 17.
    PHP 7 newreferences mechanism  In PHP 7, the deep copy is postponed until COW breakage  If no COW breakage, then no copy happens at all function foo($arg) { $arg = 'bar'; } /* full copy of the variable */ $a = 'foo'; $b = &$a; foo($a); $a = ['foo', 42, ['bar' , new stdclass], 'baz']; $b = &$a; if (count($a) == 8) { /* no zval copy here */ }
  • 18.
  • 19.
    Optimizing CPU time Latency Numbers Every Programmer Should Know  http://lwn.net/Articles/250967/  http://www.eecs.berkeley.edu/~rcs/research/interactive _latency.html 2016 numbers (may vary with chip) --------------------------------------------------- L1 cache reference 1 ns Branch mispredict 3 ns L2 cache reference 4 ns 4x L1 cache L3 cache reference 12 ns 3X L2 cache, 12x L1 cache Main memory reference 100 ns 25x L2 cache, 100x L1 cache SSD random read 16,000 ns HDD random read(seek) 200,000,000 ns
  • 20.
    Optimizing CPU cacheefficiency  If we can reduce payload size, the CPU will use its caches more often  CPU caches prefetch data on a "line" basis  Improve data locality to improve cache efficiency  https://software.intel.com/en-us/articles/optimize-data- structures-and-memory-access-patterns-to-improve- data-locality  That means in C  Reduce number of pointer indirections  Stick data together (struct hacks, struct merges)  Use smaller data sizes
  • 21.
    PHP 7 cacheefficiency  If we can reduce payload size, the CPU will use its caches more often PHP 7.1.4-dev (debug) 128,883666 task-clock (msec) 9 context-switches 0 cpu-migrations 1 768 page-faults 340 930 642 cycles 810 206 077 instructions 100 639 058 branches 187 132 branch-misses 0,131802866 seconds time elapsed PHP 5.6.31-dev (debug) 730,824226 task-clock (msec) 92 context-switches 1 cpu-migrations 74 691 page-faults 2 030 928 993 cycles 3 766 048 098 instructions 506 047 488 branches 356 931 branch-misses 0,773863158 seconds time elapsed
  • 22.
    PHP 7 optimizations Every variable in PHP is coded on a zval struct  This struct has been reorganized in PHP 7  Narrowed / shrinked  separated  Hence, every variable usage in PHP 7 is more optimized than in PHP 5
  • 23.
    PHP 5 variables value refcountis_ref type gc_info dval str_val* str_len hashtable* object* lval ast* zval zval_value ... ... HashTable 32 bytes $a 8 bytes zval * XX bytes  40 bytes + complex value size  2 indirections
  • 24.
    PHP 7 variables value type internal_int dval zend_string* object* lval ... zval zval_value ... ... HashTable 16bytes $a zval XX bytes  16 bytes + complex value size  1 indirection hashtable* gc_infos refcount infosflags gc_infos
  • 25.
    PHP 5 vsPHP 7 variable design  zval container no longer stores GC infos  No more need to heap allocate a zval *  Very less pressure on the heap allocator  GC infos stored into each complex types  each complex type may now be shared  In PHP 5, we had to share the zval containing them  PHP 7 variables are much more CPU cache efficient
  • 26.
    New Memory Allocator PHP 7 has a fully new heap memory allocator  Zend Memory Manager  It now uses several allocator pools  Huge  Medium  Small  ... for better efficiency  Uses mmap(), no more libc's malloc() overhead  May use Kernel Huge Pages if told to  Better CPU TLB usage
  • 27.
    PHP 7 newhashtables
  • 28.
    PHP 7 hashtables It has been fully rewritten, and reworked  Nothing to say from PHP userland POV  Except perhaps for the packed array case
  • 29.
  • 30.
    Packed arrays  Ifyour keys are integer only (no string key)  If your keys are constantly increasing  No matter if they don't follow each other with +1  Then you'll benefit from packed arrays optimization  Packed arrays will reduce memory size compared to "normal" array  Reduction of (table_size - 2) * 4 bytes  ~ 4Kb for a 1000 entry table  May be noticeable for BIG arrays
  • 31.
    Packed arrays example constN = 1024 * 1023; for ($i=0; $i<N; $i++) { $tab[] = random_bytes(3); } echo memory_get_usage(); const N = 1024 * 1023; for ($i=0; $i<N; $i++) { $tab[] = random_bytes(3); } $tab['foo'] = 'bar'; echo memory_get_usage(); const N = 1024 * 1023; for ($i=0; $i<N; $i++) { $tab[] = random_bytes(3); } unset($tab[1000]); $tab[1000] = 1000; echo memory_get_usage(); ~67Mb ~71Mb ~71Mb
  • 32.
    Packed arrays conditions(recalled)  Do NOT use string keys  Always use increasing integer-based keys  Contiguous or not is not important  If using the compiler, keep keys into the interval [0- table-size] , table-size being rounded to the upper power of two  For example, if you need lists , then you'll benefit from this optimisation
  • 33.
    HashTables in PHP5  Each element needs  4 pointer indirections  72 bytes for a bucket + 32 bytes for a zval zval zval * HashTable $a zval * HashTable* bucket * zval 64 bytes 72 bytesbucket
  • 34.
    HashTables in PHP7  Each element needs  2 pointer indirections  32 bytes for a bucket zval bucket HashTable $a zval HashTable* zval 56 bytes 32 bytes bucket*
  • 35.
    HashTables in PHP7 : go further  http://jpauli.github.io/2016/04/08/hashtables.html
  • 36.
  • 37.
    String management  InPHP 5, strings don't have their own structure  String management is hard  Leads to many strings duplication  And thus many memory access  In PHP 7, strings share the zend_string structure  They are refcounted, thus shareable  hashes are precomputed, often at compile time  struct hack is used to compact memory
  • 38.
    Strings in PHP char* str ... zval gc_infos int len refcount is_ref zend_string * ... zval ... hash gc_infos char str[1]size_t len ... zend_string PHP 5 PHP 7
  • 39.
    Strings in PHP5  $a = "foo"; 3 0X00007FFFF7F8C708 foo0
  • 40.
    Strings in PHP7  $a = "foo"; foo0 C struct hack 3 memory border
  • 41.
    Strings tip  Don'tforget to use OPCache  OPCache shares interned strings buffer between processes  Don't forget to size interned strings buffer according to your needs  opcache.interned_strings_buffer interned string shared memory PHP master process PHP child #1 PHP child #2 PHP child #3
  • 42.
  • 43.
    Encapsed string optimisation Encapsed string are double-quoted strings that get parsed  They need to be analyzed for variables  PHP 5 used to reallocate the string at each step $a = "foo and $b and $c"; 3 0 E > ADD_STRING ~0 'foo+and+' 1 ADD_VAR ~0 ~0, !1 2 ADD_STRING ~0 ~0, '+and+' 3 ADD_VAR ~0 ~0, !2 4 ASSIGN !0, ~0 4 5 > RETURN 1
  • 44.
    Encapsed string inPHP 5 $a = "foo and $b and $c"; 3 0 E > ADD_STRING ~0 'foo+and+' 1 ADD_VAR ~0 ~0, !1 2 ADD_STRING ~0 ~0, '+and+' 3 ADD_VAR ~0 ~0, !2 4 ASSIGN !0, ~0 4 5 > RETURN 1 foo and foo and b foo and b and foo and b and c  Lot of pressure on the allocator  Needs to find new chunk  At every new allocation  Browses through a free-chunk linked-list  Bad for performances $b = 'b'; $c = 'c';
  • 45.
    Encapsed string optimisationin PHP 7  PHP 7 uses a "rope", and only reallocates memory once, at the end  https://en.wikipedia.org/wiki/Rope_(data_structure) $a = "foo and $b and $c"; L3 #0 ROPE_INIT "foo and " ~1 L3 #1 ROPE_ADD ~1 $b ~1 L3 #2 ROPE_ADD ~1 " and " ~1 L3 #3 ROPE_END ~1 $c ~0 L3 #4 ASSIGN $a ~0 L3 #5 RETURN 1
  • 46.
    Encapsed strings inPHP 7 $a = "foo and $b and $c"; L3 #0 ROPE_INIT "foo and " ~1 L3 #1 ROPE_ADD ~1 $b ~1 L3 #2 ROPE_ADD ~1 " and " ~1 L3 #3 ROPE_END ~1 $c ~0 L3 #4 ASSIGN $a ~0 L3 #5 RETURN 1 foo and foo and b foo and b and foo and b and c foo and b and c INIT ADD ADD ADD END  Keep every piece of string as its own buffer  Stack them  At the end, merge them as one operation
  • 47.
    So ?  Soyou'd better use encapsed strings  Than concatenations $a = "foo and $b and $c"; $a = 'foo and ' . $b . ' and ' . $c;
  • 48.
  • 49.
    Future of PHP PHP 7 branch keeps optimizing things  PHP 7 branch keep preparing the massive JIT engine move that should happen for PHP 8  PHP 8 is not expected before 2020 at best  Try at first to migrate to PHP 7 branch  PHP 7.2 is on its way  Nov - Dec 2017  As usual, read wiki.php.net/rfc  PHP 5.6 will die end of 2017 , and PHP 5 branch as well
  • 50.
  • 51.
    Thank you forlistening