SlideShare una empresa de Scribd logo
1 de 46
Performances
considerations
with PHP 7
Hi
 Julien PAULI
 SensioLabs tech team (Blackfire - PHP)
 Programming with PHP since early 2000s
 Today working with PHP and hacking it from inside (C)
 PHP Internals programmer/contributor
 PHP 5.5 & 5.6 Release Manager
 @julienpauli
 Tech life at http://jpauli.tech
 jpauli@php.net
What we'll cover together
 PHP 7 new compiler
 Compiler optimizations
 PHP 7 new executor optimizers and OPCache passes
 PHP 7 new references mechanism
 PHP 7 new Hashtables (PHP arrays)
 PHP 7 new strings management
Having SF and PHP work together
The PHP language
 Born in 1995
 Fully written using the C language
 Today
 870,000 C lines of code
 dozens of contributors around the world
PHP VERSIONS SURVEY
PHP code compilation
How does PHP work ?
Parsing
(Lexer + parser)
Compiling
Executing
opcodes
PHP code
AST nodes
Result
A file-based compiler with runtime compiling
 include / require / eval() = compile + execute
 autoload = compile + execute deffered at execution
Compile Execute
include/require ?
eval() ?
autoload ?
B
N
Y
E
OPCache Optimizer
 OPCache will optimize the compilation result
opcodes
Optimizing
opcodes
Shared
Memory
opcodes
Caching
Compiling
save
Executing
opcodes
PHP 7 compiler
PHP 7 new compiler
 PHP 7 compiler is based on an AST
 It plays with OPCache to optimize the runtime
 Every hash of every litteral string is calculated at compile time
 Resolves every static/litteral expression
 Optimizes some function calls when result is known at compile
time
 Compiling a PHP file is a huge heavy process
Classes impact
 Classes are heavy structures in memory
 But objects are light structures in memory ;-)
 Don't make PHP parse huge classes
 If you won't use them fully at runtime
PHP 7 compiler optimizations
 If the compile node can be resolved at compile-time , it will be
 Static expressions, static arrays initialization
 PHP constants
 Some functions compile to special ZendVM OPCodes or are
directly resolved by the compiler if possible
 strlen(), is_{type}(), {type}val() casts, defined(), chr(), ord(),
cuf()&cufa(), get_class(), get_called_class(), gettype(), count(),
in_array(), array_slice(), func_num_args(), func_get_args()
 Some are parts of OPCache optimizer :
 function_exists(), is_callable(), extension_loaded(), constant(),
dirname(), defined(), strlen()
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.
 (Usually, IDE prepends the leading  for you)
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
Symfony example : managing several PHP versions
 PHP constants are resolved at compile time
 OPCache optimizer will delete the dead branch
public function unserialize($data)
{
if (PHP_VERSION_ID >= 70000) {
list($environment, $debug) = unserialize($data, array('allowed_classes' => false));
} else {
list($environment, $debug) = unserialize($data);
}
$this->__construct($environment, $debug);
}
public function unserialize($data)
{
list($environment, $debug) = unserialize($data, array('allowed_classes' => false));
$this->__construct($environment, $debug);
}
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']];
PHP 7 references
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 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
 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 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-lis
 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;
Some other unclassified optimizations
switch-case with special cases
 A switch-case statement with only strings as cases, will now use
a jump table instead of testing each case individually in the VM
 Same for only-integers keys, starting from at least 5 cases.
switch ($a) {
case 'bar':
echo 'bar';
break;
case 'foo':
echo 'foo';
break;
}
if ($a == 'bar') {
echo 'bar';
} elseif ($a == 'foo') {
echo 'foo';
}
in_array($a, ['bar', 'foo']);PHP >=7.2
PHP < 7.2
This is O(1) in huge majority of cases
New maths OPCode specializers
 Many of them , with overflows taken care of when needed
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_ADD,
(op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE),
ZEND_ADD_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC
(NO_CONST_CONST,COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2, *result;
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
result = EX_VAR(opline->result.var);
ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
ZEND_VM_NEXT_OPCODE();
}
JMP target propagation (OPCache)
if ($i == 9) {
if ($j == 8) {
echo "y";
} else {
goto foo;
}
} else {
foo:
echo "out";
}
L2 (6): T2 = IS_EQUAL CV0($i) int(9)
L3 (6): JMPZ T2 L8
L4 (7): T2 = IS_EQUAL CV1($j) int(8)
L5 (7): JMPZ T2 L8
L6 (8): ECHO string("y")
L7 (8): JMP L9
L8 (15): ECHO string("out")
L9 (18): ECHO CV0($i)
L10 (19): RETURN int(1)
L2 (6): T4 = IS_EQUAL CV0($i) int(9)
L3 (6): JMPZ T4 L10
L4 (7): T5 = IS_EQUAL CV1($j) int(8)
L5 (7): JMPZ T5 L8
L6 (8): ECHO string("y")
L7 (8): JMP L9
L8 (10): JMP L10
L9 (10): JMP L11
L10 (15): ECHO string("out")
L11 (18): ECHO CV0($i)
L12 (19): RETURN int(1)
Future ?
Future of PHP
 PHP 7 branch keeps optimizing things
 SSA and other dynamic optimizations have been added to
OPCache optimizer in PHP 7.1 and PHP 7.2
 PHP 7 branch keep preparing the JIT engine move that should
happen for PHP 8
 PHP 8 will come when ready :-)
 Tip : not tomorrow
Thank you for listening

Más contenido relacionado

La actualidad más candente

Quick tour of PHP from inside
Quick tour of PHP from insideQuick tour of PHP from inside
Quick tour of PHP from insidejulien pauli
 
Understanding PHP memory
Understanding PHP memoryUnderstanding PHP memory
Understanding PHP memoryjulien pauli
 
Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)julien pauli
 
The Php Life Cycle
The Php Life CycleThe Php Life Cycle
The Php Life CycleXinchen Hui
 
Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objectsjulien pauli
 
PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13julien pauli
 
How PHP Works ?
How PHP Works ?How PHP Works ?
How PHP Works ?Ravi Raj
 
PHP Optimization
PHP OptimizationPHP Optimization
PHP Optimizationdjesch
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaPatrick Allaert
 
Writing and using php streams and sockets
Writing and using php streams and socketsWriting and using php streams and sockets
Writing and using php streams and socketsElizabeth Smith
 
PHP Internals and Virtual Machine
PHP Internals and Virtual MachinePHP Internals and Virtual Machine
PHP Internals and Virtual Machinejulien pauli
 
Phpをいじり倒す10の方法
Phpをいじり倒す10の方法Phpをいじり倒す10の方法
Phpをいじり倒す10の方法Moriyoshi Koizumi
 
Streams, sockets and filters oh my!
Streams, sockets and filters oh my!Streams, sockets and filters oh my!
Streams, sockets and filters oh my!Elizabeth Smith
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in PerlLaurent Dami
 

La actualidad más candente (20)

PHP 7 new engine
PHP 7 new enginePHP 7 new engine
PHP 7 new engine
 
Quick tour of PHP from inside
Quick tour of PHP from insideQuick tour of PHP from inside
Quick tour of PHP from inside
 
Building Custom PHP Extensions
Building Custom PHP ExtensionsBuilding Custom PHP Extensions
Building Custom PHP Extensions
 
Understanding PHP memory
Understanding PHP memoryUnderstanding PHP memory
Understanding PHP memory
 
Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)
 
PHP7 is coming
PHP7 is comingPHP7 is coming
PHP7 is coming
 
The Php Life Cycle
The Php Life CycleThe Php Life Cycle
The Php Life Cycle
 
Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objects
 
PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13
 
How PHP Works ?
How PHP Works ?How PHP Works ?
How PHP Works ?
 
Php engine
Php enginePhp engine
Php engine
 
PHP Optimization
PHP OptimizationPHP Optimization
PHP Optimization
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 Verona
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
 
Writing and using php streams and sockets
Writing and using php streams and socketsWriting and using php streams and sockets
Writing and using php streams and sockets
 
PHP Internals and Virtual Machine
PHP Internals and Virtual MachinePHP Internals and Virtual Machine
PHP Internals and Virtual Machine
 
Phpをいじり倒す10の方法
Phpをいじり倒す10の方法Phpをいじり倒す10の方法
Phpをいじり倒す10の方法
 
Streams, sockets and filters oh my!
Streams, sockets and filters oh my!Streams, sockets and filters oh my!
Streams, sockets and filters oh my!
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in Perl
 
Php’s guts
Php’s gutsPhp’s guts
Php’s guts
 

Similar a SymfonyCon 2017 php7 performances

What's new, what's hot in PHP 5.3
What's new, what's hot in PHP 5.3What's new, what's hot in PHP 5.3
What's new, what's hot in PHP 5.3Jeremy Coates
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?Nikita Popov
 
Php 7 compliance workshop singapore
Php 7 compliance workshop singaporePhp 7 compliance workshop singapore
Php 7 compliance workshop singaporeDamien Seguy
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHPBradley Holt
 
Php7 hhvm and co
Php7 hhvm and coPhp7 hhvm and co
Php7 hhvm and coPierre Joye
 
Giới thiệu PHP 7
Giới thiệu PHP 7Giới thiệu PHP 7
Giới thiệu PHP 7ZendVN
 
Introduction to Modern Perl
Introduction to Modern PerlIntroduction to Modern Perl
Introduction to Modern PerlDave Cross
 
Php7 HHVM and co
Php7 HHVM and coPhp7 HHVM and co
Php7 HHVM and coweltling
 
Mastering Namespaces in PHP
Mastering Namespaces in PHPMastering Namespaces in PHP
Mastering Namespaces in PHPNick Belhomme
 
IT2255 Web Essentials - Unit IV Server-Side Processing and Scripting - PHP.pdf
IT2255 Web Essentials - Unit IV Server-Side Processing and Scripting - PHP.pdfIT2255 Web Essentials - Unit IV Server-Side Processing and Scripting - PHP.pdf
IT2255 Web Essentials - Unit IV Server-Side Processing and Scripting - PHP.pdfpkaviya
 

Similar a SymfonyCon 2017 php7 performances (20)

What's new, what's hot in PHP 5.3
What's new, what's hot in PHP 5.3What's new, what's hot in PHP 5.3
What's new, what's hot in PHP 5.3
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
 
Php 7 compliance workshop singapore
Php 7 compliance workshop singaporePhp 7 compliance workshop singapore
Php 7 compliance workshop singapore
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
 
Php7 hhvm and co
Php7 hhvm and coPhp7 hhvm and co
Php7 hhvm and co
 
Giới thiệu PHP 7
Giới thiệu PHP 7Giới thiệu PHP 7
Giới thiệu PHP 7
 
Web Technology_10.ppt
Web Technology_10.pptWeb Technology_10.ppt
Web Technology_10.ppt
 
Introduction to Modern Perl
Introduction to Modern PerlIntroduction to Modern Perl
Introduction to Modern Perl
 
Introduction to php basics
Introduction to php   basicsIntroduction to php   basics
Introduction to php basics
 
Php7 HHVM and co
Php7 HHVM and coPhp7 HHVM and co
Php7 HHVM and co
 
Mastering Namespaces in PHP
Mastering Namespaces in PHPMastering Namespaces in PHP
Mastering Namespaces in PHP
 
Php.ppt
Php.pptPhp.ppt
Php.ppt
 
extending-php
extending-phpextending-php
extending-php
 
extending-php
extending-phpextending-php
extending-php
 
extending-php
extending-phpextending-php
extending-php
 
extending-php
extending-phpextending-php
extending-php
 
extending-php
extending-phpextending-php
extending-php
 
extending-php
extending-phpextending-php
extending-php
 
PHP 7
PHP 7PHP 7
PHP 7
 
IT2255 Web Essentials - Unit IV Server-Side Processing and Scripting - PHP.pdf
IT2255 Web Essentials - Unit IV Server-Side Processing and Scripting - PHP.pdfIT2255 Web Essentials - Unit IV Server-Side Processing and Scripting - PHP.pdf
IT2255 Web Essentials - Unit IV Server-Side Processing and Scripting - PHP.pdf
 

Más de julien pauli

Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019julien pauli
 
Basics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNGBasics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNGjulien pauli
 
Mastering your home network - Do It Yourself
Mastering your home network - Do It YourselfMastering your home network - Do It Yourself
Mastering your home network - Do It Yourselfjulien pauli
 
Communications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHPCommunications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHPjulien pauli
 
PHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_ExtensionsPHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_Extensionsjulien pauli
 
PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4julien pauli
 
Patterns and OOP in PHP
Patterns and OOP in PHPPatterns and OOP in PHP
Patterns and OOP in PHPjulien pauli
 
ZendFramework2 - Présentation
ZendFramework2 - PrésentationZendFramework2 - Présentation
ZendFramework2 - Présentationjulien pauli
 
AlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHPAlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHPjulien pauli
 
Apache for développeurs PHP
Apache for développeurs PHPApache for développeurs PHP
Apache for développeurs PHPjulien pauli
 

Más de julien pauli (12)

Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019
 
Dns
DnsDns
Dns
 
Basics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNGBasics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNG
 
Mastering your home network - Do It Yourself
Mastering your home network - Do It YourselfMastering your home network - Do It Yourself
Mastering your home network - Do It Yourself
 
Tcpip
TcpipTcpip
Tcpip
 
Communications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHPCommunications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHP
 
PHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_ExtensionsPHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_Extensions
 
PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4
 
Patterns and OOP in PHP
Patterns and OOP in PHPPatterns and OOP in PHP
Patterns and OOP in PHP
 
ZendFramework2 - Présentation
ZendFramework2 - PrésentationZendFramework2 - Présentation
ZendFramework2 - Présentation
 
AlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHPAlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHP
 
Apache for développeurs PHP
Apache for développeurs PHPApache for développeurs PHP
Apache for développeurs PHP
 

Último

IP addressing and IPv6, presented by Paul Wilson at IETF 119
IP addressing and IPv6, presented by Paul Wilson at IETF 119IP addressing and IPv6, presented by Paul Wilson at IETF 119
IP addressing and IPv6, presented by Paul Wilson at IETF 119APNIC
 
Unidad 4 – Redes de ordenadores (en inglés).pptx
Unidad 4 – Redes de ordenadores (en inglés).pptxUnidad 4 – Redes de ordenadores (en inglés).pptx
Unidad 4 – Redes de ordenadores (en inglés).pptxmibuzondetrabajo
 
SCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is prediSCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is predieusebiomeyer
 
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书rnrncn29
 
Company Snapshot Theme for Business by Slidesgo.pptx
Company Snapshot Theme for Business by Slidesgo.pptxCompany Snapshot Theme for Business by Slidesgo.pptx
Company Snapshot Theme for Business by Slidesgo.pptxMario
 
Cybersecurity Threats and Cybersecurity Best Practices
Cybersecurity Threats and Cybersecurity Best PracticesCybersecurity Threats and Cybersecurity Best Practices
Cybersecurity Threats and Cybersecurity Best PracticesLumiverse Solutions Pvt Ltd
 
TRENDS Enabling and inhibiting dimensions.pptx
TRENDS Enabling and inhibiting dimensions.pptxTRENDS Enabling and inhibiting dimensions.pptx
TRENDS Enabling and inhibiting dimensions.pptxAndrieCagasanAkio
 
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书rnrncn29
 
ETHICAL HACKING dddddddddddddddfnandni.pptx
ETHICAL HACKING dddddddddddddddfnandni.pptxETHICAL HACKING dddddddddddddddfnandni.pptx
ETHICAL HACKING dddddddddddddddfnandni.pptxNIMMANAGANTI RAMAKRISHNA
 

Último (9)

IP addressing and IPv6, presented by Paul Wilson at IETF 119
IP addressing and IPv6, presented by Paul Wilson at IETF 119IP addressing and IPv6, presented by Paul Wilson at IETF 119
IP addressing and IPv6, presented by Paul Wilson at IETF 119
 
Unidad 4 – Redes de ordenadores (en inglés).pptx
Unidad 4 – Redes de ordenadores (en inglés).pptxUnidad 4 – Redes de ordenadores (en inglés).pptx
Unidad 4 – Redes de ordenadores (en inglés).pptx
 
SCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is prediSCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is predi
 
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
 
Company Snapshot Theme for Business by Slidesgo.pptx
Company Snapshot Theme for Business by Slidesgo.pptxCompany Snapshot Theme for Business by Slidesgo.pptx
Company Snapshot Theme for Business by Slidesgo.pptx
 
Cybersecurity Threats and Cybersecurity Best Practices
Cybersecurity Threats and Cybersecurity Best PracticesCybersecurity Threats and Cybersecurity Best Practices
Cybersecurity Threats and Cybersecurity Best Practices
 
TRENDS Enabling and inhibiting dimensions.pptx
TRENDS Enabling and inhibiting dimensions.pptxTRENDS Enabling and inhibiting dimensions.pptx
TRENDS Enabling and inhibiting dimensions.pptx
 
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
 
ETHICAL HACKING dddddddddddddddfnandni.pptx
ETHICAL HACKING dddddddddddddddfnandni.pptxETHICAL HACKING dddddddddddddddfnandni.pptx
ETHICAL HACKING dddddddddddddddfnandni.pptx
 

SymfonyCon 2017 php7 performances

  • 2. Hi  Julien PAULI  SensioLabs tech team (Blackfire - PHP)  Programming with PHP since early 2000s  Today working with PHP and hacking it from inside (C)  PHP Internals programmer/contributor  PHP 5.5 & 5.6 Release Manager  @julienpauli  Tech life at http://jpauli.tech  jpauli@php.net
  • 3. What we'll cover together  PHP 7 new compiler  Compiler optimizations  PHP 7 new executor optimizers and OPCache passes  PHP 7 new references mechanism  PHP 7 new Hashtables (PHP arrays)  PHP 7 new strings management
  • 4. Having SF and PHP work together
  • 5. The PHP language  Born in 1995  Fully written using the C language  Today  870,000 C lines of code  dozens of contributors around the world
  • 8. How does PHP work ? Parsing (Lexer + parser) Compiling Executing opcodes PHP code AST nodes Result
  • 9. A file-based compiler with runtime compiling  include / require / eval() = compile + execute  autoload = compile + execute deffered at execution Compile Execute include/require ? eval() ? autoload ? B N Y E
  • 10. OPCache Optimizer  OPCache will optimize the compilation result opcodes Optimizing opcodes Shared Memory opcodes Caching Compiling save Executing opcodes
  • 12. PHP 7 new compiler  PHP 7 compiler is based on an AST  It plays with OPCache to optimize the runtime  Every hash of every litteral string is calculated at compile time  Resolves every static/litteral expression  Optimizes some function calls when result is known at compile time  Compiling a PHP file is a huge heavy process
  • 13. Classes impact  Classes are heavy structures in memory  But objects are light structures in memory ;-)  Don't make PHP parse huge classes  If you won't use them fully at runtime
  • 14. PHP 7 compiler optimizations  If the compile node can be resolved at compile-time , it will be  Static expressions, static arrays initialization  PHP constants  Some functions compile to special ZendVM OPCodes or are directly resolved by the compiler if possible  strlen(), is_{type}(), {type}val() casts, defined(), chr(), ord(), cuf()&cufa(), get_class(), get_called_class(), gettype(), count(), in_array(), array_slice(), func_num_args(), func_get_args()  Some are parts of OPCache optimizer :  function_exists(), is_callable(), extension_loaded(), constant(), dirname(), defined(), strlen()
  • 15. 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
  • 16. 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
  • 17. Namespaced function calls  We have proven that the performance difference is really tiny on real use cases.  (Usually, IDE prepends the leading for you) 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
  • 18. Symfony example : managing several PHP versions  PHP constants are resolved at compile time  OPCache optimizer will delete the dead branch public function unserialize($data) { if (PHP_VERSION_ID >= 70000) { list($environment, $debug) = unserialize($data, array('allowed_classes' => false)); } else { list($environment, $debug) = unserialize($data); } $this->__construct($environment, $debug); } public function unserialize($data) { list($environment, $debug) = unserialize($data, array('allowed_classes' => false)); $this->__construct($environment, $debug); }
  • 19. 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']];
  • 21. 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 */ }
  • 22. PHP 7 new hashtables
  • 23. PHP 7 hashtables  It has been fully rewritten, and reworked  Nothing to say from PHP userland POV  Except perhaps for the packed array case
  • 24. 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
  • 25. 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
  • 26. 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
  • 27. HashTables in PHP 7 : go further  http://jpauli.github.io/2016/04/08/hashtables.html
  • 29. 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
  • 30. 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
  • 31. Strings in PHP 5  $a = "foo"; 3 0X00007FFFF7F8C708 foo0
  • 32. Strings in PHP 7  $a = "foo"; foo0 C struct hack 3 memory border
  • 33. 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
  • 35. 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
  • 36. 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-lis  Bad for performances $b = 'b'; $c = 'c';
  • 37. 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
  • 38. 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
  • 39. So ?  So you'd better use encapsed strings  Than concatenations $a = "foo and $b and $c"; $a = 'foo and ' . $b . ' and ' . $c;
  • 40. Some other unclassified optimizations
  • 41. switch-case with special cases  A switch-case statement with only strings as cases, will now use a jump table instead of testing each case individually in the VM  Same for only-integers keys, starting from at least 5 cases. switch ($a) { case 'bar': echo 'bar'; break; case 'foo': echo 'foo'; break; } if ($a == 'bar') { echo 'bar'; } elseif ($a == 'foo') { echo 'foo'; } in_array($a, ['bar', 'foo']);PHP >=7.2 PHP < 7.2 This is O(1) in huge majority of cases
  • 42. New maths OPCode specializers  Many of them , with overflows taken care of when needed ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_ADD, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_ADD_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC (NO_CONST_CONST,COMMUTATIVE)) { USE_OPLINE zval *op1, *op2, *result; op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); result = EX_VAR(opline->result.var); ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); ZEND_VM_NEXT_OPCODE(); }
  • 43. JMP target propagation (OPCache) if ($i == 9) { if ($j == 8) { echo "y"; } else { goto foo; } } else { foo: echo "out"; } L2 (6): T2 = IS_EQUAL CV0($i) int(9) L3 (6): JMPZ T2 L8 L4 (7): T2 = IS_EQUAL CV1($j) int(8) L5 (7): JMPZ T2 L8 L6 (8): ECHO string("y") L7 (8): JMP L9 L8 (15): ECHO string("out") L9 (18): ECHO CV0($i) L10 (19): RETURN int(1) L2 (6): T4 = IS_EQUAL CV0($i) int(9) L3 (6): JMPZ T4 L10 L4 (7): T5 = IS_EQUAL CV1($j) int(8) L5 (7): JMPZ T5 L8 L6 (8): ECHO string("y") L7 (8): JMP L9 L8 (10): JMP L10 L9 (10): JMP L11 L10 (15): ECHO string("out") L11 (18): ECHO CV0($i) L12 (19): RETURN int(1)
  • 45. Future of PHP  PHP 7 branch keeps optimizing things  SSA and other dynamic optimizations have been added to OPCache optimizer in PHP 7.1 and PHP 7.2  PHP 7 branch keep preparing the JIT engine move that should happen for PHP 8  PHP 8 will come when ready :-)  Tip : not tomorrow
  • 46. Thank you for listening