Confidential - © All rights reserved. Zend Technologies, Inc.1
Copyright - © All rights reserved. Zend Technologies, Inc.
Анализ внутренних изменений PHP 7
Dmitry Stogov
CodeFest 2016, Новосибирск
Principal Engineer at Zend Technologies
Copyright - © All rights reserved. Zend Technologies, Inc.2
PHP – Personal Home Page
●
Инструмент для создания персональных веб-страниц
●
Первый релиз PHP/FI 2.0 от Rasmus Lerdorf 8 июня 1995
●
В 1998 Andi Gutmans и Zeev Suraski выпустили PHP 3
●
PHP 4 основанный на Zend Engine вышел в 2000
●
PHP 5 с переработанным функционалом ООП вышел в 2004
●
ZendFramework в 2007
●
Сегодня более 70% сайтов интернета используют PHP
●
C 2010 Facebook работает над альтернативной реализацией - HHVM
●
В декабре 2015 вышел PHP 7
Copyright - © All rights reserved. Zend Technologies, Inc.3
Кто Я?
●
Работаю в ИТ с 1991
●
Первое знакомство с PHP в 2002
●
Автор Turck MMCache (eAccelerator)
●
Работаю в Zend Technologies с 2004
●
Сейчас ведущий инженер
●
Автор ext/soap и pecl/perl
●
Один из ведущих разработчиков Open Source PHP
●
Майнтейнер Zend OPcache
●
Лидер проекта PHPNG легшего в основу PHP 7
Copyright - © All rights reserved. Zend Technologies, Inc.4
Производительность PHP
0 2 4 6 8 10 12 14
12.68
12.54
4.68
4.2
2.91
2.18
2.03
1.92
0.78
0.38
bench.php [sec]
4.4
5.0 - Jul 2004
5.1 - Nov 2005
5.2 - Nov 2006
5.3 - Nov 2009
5.4 - Mar 2012
5.5 - Jun 2013
5.6 - Aug 2014
7.0.0 - Dec 2015
HHVM-3.10.0
secAre we there?
Copyright - © All rights reserved. Zend Technologies, Inc.5
PHPNG (New Generation)
●
Проект получил свое развитие после попыток создания JIT для PHP
●
Рефакторинг (ни каких нововведений, 100% совместимость с PHP 5)
●
Основная цель — достичь нового уровня производительности и
заложить базу для будущих улучшений
●
Отделился от основной ветки PHP в январе 2014
●
Две недели ушло на то что-бы просто скомпилировать ядро
●
Еще через две недели заработал bench.php
●
Полтора месяца для обеспечения совместимости с Wordpress
●
Еще через месяц (к 9 Мая) мы открыли проект
●
В августе 2014 принят как основа для будущего PHP 7
Copyright - © All rights reserved. Zend Technologies, Inc.6
PHP 7
●
Было решено выпускать PHP 7 после PHP 5, пропустив PHP 6
●
GA релиз состоялся в декабре 2015
●
Сейчас доступен PHP-7.0.4
●
Возможность определять скалярные типы аргументов функций и
возвращаемых значений
●
Исключения вместо фатальных ошибок
●
Анонимный классы
●
Zero-cost assert()
●
Новые операторы и функции (<=>, ??)
●
Чистка неконсистентностей
Copyright - © All rights reserved. Zend Technologies, Inc.7
Производительность PHP
0 50 100 150 200 250
54
51
56
67
76
91
93
101
232
206
WordPress-3.6.0 Home Page [req/sec]
4.4
5.0 - Jul 2004
5.1 - Nov 2005
5.2 - Nov 2006
5.3 - Nov 2009
5.4 - Mar 2012
5.5 - Jun 2013
5.6 - Aug 2014
7.0.0 - Dec 2015
HHVM-3.10.0
req/sec
We are here!
Copyright - © All rights reserved. Zend Technologies, Inc.8
zval (PHP 5)
typedef struct _zval_struct {
union {
long lval;
double dval;
struct {
char *val;
int len;
} str;
HashTable *ht;
struct {
zend_object_handle handle;
zend_object_handlers *handlers;
} obj;
} value;
zend_uint refcount;
zend_uchar type;
zend_uchar is_ref;
} zval;
sizeof(zval) == 24
$a = 1; $b = $a; $c = «hello»; $d = $c;
$b
$c
$a
$d
VM STACK (pointers to zvals) HEAP
string( ), rc=2
int(1), rc=2
«hello»
● read type - 2 CPU instructions
● read int value - 2 CPU instructions
● read string value - 3 CPU instructions
Copyright - © All rights reserved. Zend Technologies, Inc.9
zval (PHP 5 PHP 7)→
typedef struct _zval_struct {
union {
long lval;
double dval;
struct {
char *val;
int len;
} str;
HashTable *ht;
struct {
zend_object_handle handle;
zend_object_handlers *handlers;
} obj;
} value;
zend_uint refcount;
zend_uchar type;
zend_uchar is_ref;
} zval;
sizeof(zval) == 24
typedef struct _zval_struct {
union {
zend_long lval;
double dval;
zend_refcounted *counted;
zend_string *str;
zend_array *arr;
zend_object *obj;
zend_resource *res;
zend_reference *ref;
zval *zv;
void *ptr;
} value;
union {
struct {
zend_uchar type;
zend_uchar type_flags;
} v;
zend_uint type_info;
};
uint32_t reserved;
} zval;
sizeof(zval) == 16
new
Copyright - © All rights reserved. Zend Technologies, Inc.10
zval (PHP 5 PHP 7)→
● read type - 1 CPU instruction
● read int value - 1 CPU instruction
● read string value - 2 CPU instructions
$b
$c
$a
$d
int(1)
string( )
int(1)
string( )
VM STACK (zvals) HEAP
string, rc=2
«hello»
$a = 1; $b = $a; $c = «hello»; $d = $c;
$b
$c
$a
$d
VM STACK (pointers to zvals) HEAP
string( ), rc=2
int(1), rc=2
«hello»
● read type - 2 CPU instructions
● read int value - 2 CPU instructions
● read string value - 3 CPU instructions
Copyright - © All rights reserved. Zend Technologies, Inc.11
zval (PHP 5 PHP 7) Copy On Write→
● no CoW for scalars – few instructions
$b
$c
$a
$d
int(2)
string( )
int(1)
string( )
VM STACK (zvals) HEAP
string, rc=2
«hello»
$a = 1; $b = $a; $c = «hello»; $d = $c; $b = 2;
$b
$c
$a
$d
VM STACK (pointers to zvals) HEAP
string( ), rc=2
int(1), rc=1
«hello»
● CoW - hundreds CPU instructions
int(2), rc=1
Copyright - © All rights reserved. Zend Technologies, Inc.12
zval
type_flags
value
type reserved
● IS_UNDEF
● IS_NULL
● IS_FALSE
● IS_TRUE
● IS_LONG
● IS_DOUBLE
● IS_STRING
● IS_ARRAY
● IS_OBJECT
● IS_RESOURCE
● IS_REFERENCE
● IS_INDIRECT
● IS_PTR
● IS_TYPE_CONSTANT
● IS_TYPE_REFCOUNTED
● IS_TYPE_COLLECTABLE
● IS_TYPE_COPYABLE
● IS_TYPE_IMMUTABLE
0 7 8 31 32 63
new type
old IS_BOOL
scalars
refcounted
new type
Copyright - © All rights reserved. Zend Technologies, Inc.13
zval (refcounted)
● IS_STRING
● IS_ARRAY
● IS_OBJECT
● IS_RESOURCE
● IS_REFERENCE
type_flags
value
type reserved
...
typerefcount flags gc_info
0 7 8 31 32 63
Copyright - © All rights reserved. Zend Technologies, Inc.14
zval (string)
● IS_STR_PERSISTENT
● IS_STR_INTERNED
● IS_STR_PERMANENTflags
value
type reserved
hash_value
typerefcount flags gc_info
len
val
...
0 7 8 31 32 63
Copyright - © All rights reserved. Zend Technologies, Inc.15
zval (array)
flags
value
type reserved
typerefcount flags gc_info
HashTable
● IS_ARRAY_IMMUTABLE
0 7 8 31 32 63
Copyright - © All rights reserved. Zend Technologies, Inc.16
PHP 5.6 PHP 7
Memory Usage 428 MB 34 MB
Time 0.49 sec 0.06 sec
$a = array();
for ($i = 0; $i < 1000000; $i++) $a[$i] = array("hello");
echo memory_get_usage(true);
if (in array($color, array(“red”, “yellow”, “green”)) {
...
}
Immutable Arrays (Неизменяемые массивы)
Copyright - © All rights reserved. Zend Technologies, Inc.17
zval (object/PHP 5)
handlers
zend_class_entry *ce
typerefcount is_ref unused
zval *propertyN
HashTable *guards
0 7 8 31 32 63
handle
...
...
...
HashTable *properies
zval *property1
...
zval
zval
HEAP
OBJECT STORE
Copyright - © All rights reserved. Zend Technologies, Inc.18
zval (object/PHP 7)
● IS_OBJ_DTOR_CALLED
● IS_OBJ_FREE_CALLED
● IS_OBJ_USE_GUARDS
● IS_OBJ_HAS_GUARDS
flags
value
type reserved
zend_class_entry *ce
typerefcount flags gc_info
zend_object_handlers *handlers
HashTable *properies
...
zval property_N
zval property1
HashTable *guards (optional)
0 7 8 31 32 63
Copyright - © All rights reserved. Zend Technologies, Inc.19
zval (reference)
flags
value
type reserved
typerefcount flags gc_info
zval val
0 7 8 31 32 63
Copyright - © All rights reserved. Zend Technologies, Inc.20
HashTable (PHP 5.*)
nKeyLenght
hash_val
Bucket
pData
pDataPtr
pListNext
pListPrev
pNext
pPrev
arKey
pInternalPointer
nTableSize
nNextFreeElement
nTableMask
nNumOfElem
pListHead
pListTail
arBuckets
pDestructor
HashTable
nKeyLenght
hash_val
Bucket
pData
pDataPtr
pListNext
pListPrev
pNext
pPrev
arKey
type
value
zval
Bucket*
Bucket*
...
Bucket*
«hello»
Copyright - © All rights reserved. Zend Technologies, Inc.21
HashTable (PHP 7)
Bucket index N
...
Bucket index 0
key
hash_val
Bucket 0
val
...
key
hash_val
Bucket N
val
gc
flags
arData
nTableMask
nNumUsed nNumOfElem
nNextFreeElement
HashTable/zend_array
nInternalPtrnTableSize
pDestructor
string, rc=1
«hello»
Copyright - © All rights reserved. Zend Technologies, Inc.22
HashTable
●
Размер HashTable уменьшен с 72 до 56 bytes
● Размер каждого Bucket-а уменьшен с 72 до 32 bytes
● Пространство выделяется под все Bucket-ы сразу
● Bucket.key теперь указатель на zend_string и не должен копироваться
(достаточно увеличения счетчика ссылок)
● Значения элементов массива (zval) встроены в Bucket-ы и не требуют
выделения памяти
● Улучшена “data locality” => меньше промахов в кашах CPU
Copyright - © All rights reserved. Zend Technologies, Inc.23
zval (IS_BOOL -> IS_FALSE + IS_TRUE)
ZEND_VM_HANDLER(43, ZEND_JMPZ,
CONST|TMP|VAR|CV, ANY)
{
long ret;
zval *val =
GET_OP1_ZVAL_PTR(BP_VAR_R);
if (Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
} else {
ret = i_zend_is_true(val TSRMLS_CC);
FREE_OP1();
CHECK_EXCEPTION();
}
if (!ret) {
ZEND_VM_SET_OPCODE(
opline->op2.jmp_addr);
ZEND_VM_CONTINUE();
}
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(43, ZEND_JMPZ,
CONST|TMP|VAR|CV, ANY)
{
zval *val =
GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
if (Z_TYPE_P(val) == IS_TRUE) {
ZEND_VM_SET_OPCODE(opline + 1);
ZEND_VM_CONTINUE();
} else if (Z_TYPE_P(val) <= IS_TRUE) {
ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
ZEND_VM_CONTINUE();
}
if (i_zend_is_true(val TSRMLS_CC)) {
opline++;
} else {
opline = opline->op2.jmp_addr;
}
FREE_OP1();
ZEND_VM_JMP(opline);
}
type check
value read
value check
type check
slow path
slow path
Copyright - © All rights reserved. Zend Technologies, Inc.24
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
...
...
...
Copyright - © All rights reserved. Zend Technologies, Inc.25
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
...
... int(3), rc=1
HEAP
Arg1:
Arg2:
Copyright - © All rights reserved. Zend Technologies, Inc.26
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
... int(3), rc=1
int(5), rc=1
HEAP
Arg1:
Arg2:
Copyright - © All rights reserved. Zend Technologies, Inc.27
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
CALL FRAME
...
...
...
... int(3), rc=1
int(5), rc=1
HEAP
Arg1:
Arg2:
$a:
$b:
Copyright - © All rights reserved. Zend Technologies, Inc.28
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
CALL FRAME
...
...
... int(3), rc=2
int(5), rc=1
HEAP
Arg1:
Arg2:
$a:
$b:
Copyright - © All rights reserved. Zend Technologies, Inc.29
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
CALL FRAME
...
... int(3), rc=2
int(5), rc=2
HEAP
Arg1:
Arg2:
$a:
$b:
Copyright - © All rights reserved. Zend Technologies, Inc.30
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
CALL FRAME
int(8)
... int(3), rc=2
int(5), rc=2
HEAP
Arg1:
Arg2:
$a:
$b:
Copyright - © All rights reserved. Zend Technologies, Inc.31
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
CALL FRAME
int(8)
... int(3), rc=2
int(5), rc=2
HEAP
Arg1:
Arg2:
$a:
$b:
Copyright - © All rights reserved. Zend Technologies, Inc.32
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
...
...
...
Copyright - © All rights reserved. Zend Technologies, Inc.33
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (zvals)
...SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
new instruction
embedded zvals
instead of pointers
Copyright - © All rights reserved. Zend Technologies, Inc.34
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (zvals)
CALL FRAME
...
...
...
...SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
Arg1:
Arg2:
Copyright - © All rights reserved. Zend Technologies, Inc.35
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (zvals)
CALL FRAME
int(3)
...
...
...SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
Arg1:
Arg2:
Copyright - © All rights reserved. Zend Technologies, Inc.36
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (zvals)
CALL FRAME
int(3)
int(5)
...
...SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
Arg1:
Arg2:
Copyright - © All rights reserved. Zend Technologies, Inc.37
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (zvals)
CALL FRAME
int(3)
int(5)
...
...SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
skip first 2 instructions
Arg1, $a:
Arg2, $b:
local variables already in-place
Copyright - © All rights reserved. Zend Technologies, Inc.38
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (zvals)
CALL FRAME
int(3)
int(5)
int(8)
...SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
Arg1, $a:
Arg2, $b:
Copyright - © All rights reserved. Zend Technologies, Inc.39
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (zvals)
CALL FRAME
int(3)
int(5)
int(8)
...SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
Arg1, $a:
Arg2, $b:
Copyright - © All rights reserved. Zend Technologies, Inc.40
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (zvals)
...SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
NOTE:
● func_get_arg*() changed behavior
● function foo($_, $_) {} is not allowed
Copyright - © All rights reserved. Zend Technologies, Inc.41
Новый менеджер памяти
●
В PHP 5 менеджмент памяти потребляет более 20% процессорного времени
(на Wordpress)
●
Новый ММ отказался от алгоритмов dlmalloc и перешел на что-то
напоминающее jemalloc
●
Уменьшены издержки памяти на служебную информацию
●
Использование поиска по битовой маске вместо обхода списков и деревьев
●
Лучшее использование кэшей CPU
●
Специализация под часто используемые размеры блоков
●
Полностью прозрачная реализация
●
Накладные расходы ММ уменьшены до 5%
Copyright - © All rights reserved. Zend Technologies, Inc.42
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za|b",
&value, &array, &strict) == FAILURE) {
return;
}
ZEND_PARSE_PARAMETERS_START(3, 2)
Z_PARAM_ZVAL(value)
Z_PARAM_ARRAY(array)
Z_PARAM_OPTIONAL
Z_PARAM_BOOL(strict)
ZEND_PARSE_PARAMETERS_END();
Быстрое API для разбора параметров
●
В PHP 5 5% времени тратится на разбор параметров
внутренних функций
●
Для некоторых простых функций время на разбор параметров
составляет более 90%
Copyright - © All rights reserved. Zend Technologies, Inc.43
Множество мелких усовершенствований
●
Новые инструкции VM (конкатенация строк, специализация, супер-инструкции)
●
Некоторые внутренние функции превращены в инструкции VM (strlen, is_int)
●
Использование регистров CPU под регистры VM (IP и FP)
●
Новый API для итерации по HashTable
●
Оптимизация функций дублирования и удаления массивов
●
Использования счетчиков ссылок вместо копирования везде где можно
●
PCRE JIT
●
Оптимизация внутренних функций
●
Оптимизация serialize()
●
Уменьшение размера кода и обрабатываемых данных
Copyright - © All rights reserved. Zend Technologies, Inc.44
Откуда ускорение? (WordPress/PHP 5.6)
Copyright - © All rights reserved. Zend Technologies, Inc.45
Откуда ускорение? (WordPress/PHP 7.0)
Copyright - © All rights reserved. Zend Technologies, Inc.46
PHP 5.6 PHP 7.0 улучшение
VM 27% 19,494M 46% 9,005M 2 раза
alloc 22% 15,575M 5% 905M 17 раз
hash 13% 9,590M 13% 2.450M 4 раза
libc 6% 4.585M 8% 1,598M 3 раза
Total: 100% 70,798M 100% 19,462M 3.5 раз
Откуда ускорение? (WordPress)
Copyright - © All rights reserved. Zend Technologies, Inc.47
Производительность PHP 7
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov
0
5
10
15
20
25
30
24.04 24.04 24.04
22.64
18.62
16.37
15.28 14.86
14.16 13.83 13.56 13.28
12.58 12.39
11.67 11.48 11.08 11.04 10.88 10.69 10.5 10.4 10.4
sec
●
Время исполнения 1000 запросов к Wordpress-3.6.0
●
php-cgi -T 1000 /.../wordpress/index.php > /dev/null
Copyright - © All rights reserved. Zend Technologies, Inc.48
PHP-5.6 PHP-7.0.0 разница HHVM-3.10.0 разница
ZF1 Hello 1,144 2,557 124% 1,526 40%
ZF2 Test 258 614 138% 390 36%
Magento (home) 43 73 70% 65 11%
SugarCRM (login) 134 307 129% 204 34%
Laravel 304 553 82% 447 19%
Drupal 7 192 372 94% 331 11%
Drupal 8 428 655 94% 526 11%
Mediawiki 46 79 72% 85 -8%
Wordpress-4.1 92 222 82% 210 19%
PHP 5.6 против PHP 7.0 против HHVM
Copyright - © All rights reserved. Zend Technologies, Inc.49
PHP 5.6 против PHP 7.0 против HHVM
ZF1 Hello
ZF2 Test
Magento (home)
SugarCRM (login)
Laravel
Drupal 7
Drupal 8
Mediawiki
Wordpress-4.1
0
0.5
1
1.5
2
2.5
3
PHP 5.6
PHP 7.0
HHVM 3.10.0
Copyright - © All rights reserved. Zend Technologies, Inc.50
PHP 5 против PHP 7 против HHVM (версия Facebook)
Copyright - © All rights reserved. Zend Technologies, Inc.51
Проверка в деле
Copyright - © All rights reserved. Zend Technologies, Inc.52
Badoo перешли на PHP 7.0 и сэкономили $1M
Copyright - © All rights reserved. Zend Technologies, Inc.53
Badoo перешли на PHP 7.0 и сэкономили $1M
Copyright - © All rights reserved. Zend Technologies, Inc.54
Badoo перешли на PHP 7.0 и сэкономили $1M
Copyright - © All rights reserved. Zend Technologies, Inc.55
Что дальше?
●
Попробуем обойтись без революционных внутренних изменений
●
Анализатор потоков данных и глобальный оптимизатор для байт-кода PHP
●
Вывод типов
●
Использование типизированных инструкций (ADD, ADD_LONG, ADD_DOUBLE)
●
Экстра-специализация инструкций (DO_FCALL_RET, DO_FCALL_NORET)
●
Оптимизация диспетчеризации виртуальных инструкций (надо менять GCC)
●
Надо что-то делать с CALL/RETURN.
●
И еще раз JIT?
Copyright - © All rights reserved. Zend Technologies, Inc.56
Что дальше?
0 2 4 6 8 10 12 14
12.68
12.54
4.68
4.2
2.91
2.18
2.03
1.92
0.78
0.6
0.36
bench.php [sec]
4.4
5.0 - Jul 2004
5.1 - Nov 2005
5.2 - Nov 2006
5.3 - Nov 2009
5.4 - Mar 2012
5.5 - Jun 2013
5.6 - Aug 2014
7.0.0 - Dec 2015
7.1-dev Mar 2016
HHVM-3.12.1
secNext Step!
Confidential - © All rights reserved. Zend Technologies, Inc.57
Вопросы?
Dmitry Stogov
Principal Engineer at Zend Technologies
@dstogov
dmitry@zend.com
www.zend.com

Дмитрий Стогов

  • 1.
    Confidential - ©All rights reserved. Zend Technologies, Inc.1 Copyright - © All rights reserved. Zend Technologies, Inc. Анализ внутренних изменений PHP 7 Dmitry Stogov CodeFest 2016, Новосибирск Principal Engineer at Zend Technologies
  • 2.
    Copyright - ©All rights reserved. Zend Technologies, Inc.2 PHP – Personal Home Page ● Инструмент для создания персональных веб-страниц ● Первый релиз PHP/FI 2.0 от Rasmus Lerdorf 8 июня 1995 ● В 1998 Andi Gutmans и Zeev Suraski выпустили PHP 3 ● PHP 4 основанный на Zend Engine вышел в 2000 ● PHP 5 с переработанным функционалом ООП вышел в 2004 ● ZendFramework в 2007 ● Сегодня более 70% сайтов интернета используют PHP ● C 2010 Facebook работает над альтернативной реализацией - HHVM ● В декабре 2015 вышел PHP 7
  • 3.
    Copyright - ©All rights reserved. Zend Technologies, Inc.3 Кто Я? ● Работаю в ИТ с 1991 ● Первое знакомство с PHP в 2002 ● Автор Turck MMCache (eAccelerator) ● Работаю в Zend Technologies с 2004 ● Сейчас ведущий инженер ● Автор ext/soap и pecl/perl ● Один из ведущих разработчиков Open Source PHP ● Майнтейнер Zend OPcache ● Лидер проекта PHPNG легшего в основу PHP 7
  • 4.
    Copyright - ©All rights reserved. Zend Technologies, Inc.4 Производительность PHP 0 2 4 6 8 10 12 14 12.68 12.54 4.68 4.2 2.91 2.18 2.03 1.92 0.78 0.38 bench.php [sec] 4.4 5.0 - Jul 2004 5.1 - Nov 2005 5.2 - Nov 2006 5.3 - Nov 2009 5.4 - Mar 2012 5.5 - Jun 2013 5.6 - Aug 2014 7.0.0 - Dec 2015 HHVM-3.10.0 secAre we there?
  • 5.
    Copyright - ©All rights reserved. Zend Technologies, Inc.5 PHPNG (New Generation) ● Проект получил свое развитие после попыток создания JIT для PHP ● Рефакторинг (ни каких нововведений, 100% совместимость с PHP 5) ● Основная цель — достичь нового уровня производительности и заложить базу для будущих улучшений ● Отделился от основной ветки PHP в январе 2014 ● Две недели ушло на то что-бы просто скомпилировать ядро ● Еще через две недели заработал bench.php ● Полтора месяца для обеспечения совместимости с Wordpress ● Еще через месяц (к 9 Мая) мы открыли проект ● В августе 2014 принят как основа для будущего PHP 7
  • 6.
    Copyright - ©All rights reserved. Zend Technologies, Inc.6 PHP 7 ● Было решено выпускать PHP 7 после PHP 5, пропустив PHP 6 ● GA релиз состоялся в декабре 2015 ● Сейчас доступен PHP-7.0.4 ● Возможность определять скалярные типы аргументов функций и возвращаемых значений ● Исключения вместо фатальных ошибок ● Анонимный классы ● Zero-cost assert() ● Новые операторы и функции (<=>, ??) ● Чистка неконсистентностей
  • 7.
    Copyright - ©All rights reserved. Zend Technologies, Inc.7 Производительность PHP 0 50 100 150 200 250 54 51 56 67 76 91 93 101 232 206 WordPress-3.6.0 Home Page [req/sec] 4.4 5.0 - Jul 2004 5.1 - Nov 2005 5.2 - Nov 2006 5.3 - Nov 2009 5.4 - Mar 2012 5.5 - Jun 2013 5.6 - Aug 2014 7.0.0 - Dec 2015 HHVM-3.10.0 req/sec We are here!
  • 8.
    Copyright - ©All rights reserved. Zend Technologies, Inc.8 zval (PHP 5) typedef struct _zval_struct { union { long lval; double dval; struct { char *val; int len; } str; HashTable *ht; struct { zend_object_handle handle; zend_object_handlers *handlers; } obj; } value; zend_uint refcount; zend_uchar type; zend_uchar is_ref; } zval; sizeof(zval) == 24 $a = 1; $b = $a; $c = «hello»; $d = $c; $b $c $a $d VM STACK (pointers to zvals) HEAP string( ), rc=2 int(1), rc=2 «hello» ● read type - 2 CPU instructions ● read int value - 2 CPU instructions ● read string value - 3 CPU instructions
  • 9.
    Copyright - ©All rights reserved. Zend Technologies, Inc.9 zval (PHP 5 PHP 7)→ typedef struct _zval_struct { union { long lval; double dval; struct { char *val; int len; } str; HashTable *ht; struct { zend_object_handle handle; zend_object_handlers *handlers; } obj; } value; zend_uint refcount; zend_uchar type; zend_uchar is_ref; } zval; sizeof(zval) == 24 typedef struct _zval_struct { union { zend_long lval; double dval; zend_refcounted *counted; zend_string *str; zend_array *arr; zend_object *obj; zend_resource *res; zend_reference *ref; zval *zv; void *ptr; } value; union { struct { zend_uchar type; zend_uchar type_flags; } v; zend_uint type_info; }; uint32_t reserved; } zval; sizeof(zval) == 16 new
  • 10.
    Copyright - ©All rights reserved. Zend Technologies, Inc.10 zval (PHP 5 PHP 7)→ ● read type - 1 CPU instruction ● read int value - 1 CPU instruction ● read string value - 2 CPU instructions $b $c $a $d int(1) string( ) int(1) string( ) VM STACK (zvals) HEAP string, rc=2 «hello» $a = 1; $b = $a; $c = «hello»; $d = $c; $b $c $a $d VM STACK (pointers to zvals) HEAP string( ), rc=2 int(1), rc=2 «hello» ● read type - 2 CPU instructions ● read int value - 2 CPU instructions ● read string value - 3 CPU instructions
  • 11.
    Copyright - ©All rights reserved. Zend Technologies, Inc.11 zval (PHP 5 PHP 7) Copy On Write→ ● no CoW for scalars – few instructions $b $c $a $d int(2) string( ) int(1) string( ) VM STACK (zvals) HEAP string, rc=2 «hello» $a = 1; $b = $a; $c = «hello»; $d = $c; $b = 2; $b $c $a $d VM STACK (pointers to zvals) HEAP string( ), rc=2 int(1), rc=1 «hello» ● CoW - hundreds CPU instructions int(2), rc=1
  • 12.
    Copyright - ©All rights reserved. Zend Technologies, Inc.12 zval type_flags value type reserved ● IS_UNDEF ● IS_NULL ● IS_FALSE ● IS_TRUE ● IS_LONG ● IS_DOUBLE ● IS_STRING ● IS_ARRAY ● IS_OBJECT ● IS_RESOURCE ● IS_REFERENCE ● IS_INDIRECT ● IS_PTR ● IS_TYPE_CONSTANT ● IS_TYPE_REFCOUNTED ● IS_TYPE_COLLECTABLE ● IS_TYPE_COPYABLE ● IS_TYPE_IMMUTABLE 0 7 8 31 32 63 new type old IS_BOOL scalars refcounted new type
  • 13.
    Copyright - ©All rights reserved. Zend Technologies, Inc.13 zval (refcounted) ● IS_STRING ● IS_ARRAY ● IS_OBJECT ● IS_RESOURCE ● IS_REFERENCE type_flags value type reserved ... typerefcount flags gc_info 0 7 8 31 32 63
  • 14.
    Copyright - ©All rights reserved. Zend Technologies, Inc.14 zval (string) ● IS_STR_PERSISTENT ● IS_STR_INTERNED ● IS_STR_PERMANENTflags value type reserved hash_value typerefcount flags gc_info len val ... 0 7 8 31 32 63
  • 15.
    Copyright - ©All rights reserved. Zend Technologies, Inc.15 zval (array) flags value type reserved typerefcount flags gc_info HashTable ● IS_ARRAY_IMMUTABLE 0 7 8 31 32 63
  • 16.
    Copyright - ©All rights reserved. Zend Technologies, Inc.16 PHP 5.6 PHP 7 Memory Usage 428 MB 34 MB Time 0.49 sec 0.06 sec $a = array(); for ($i = 0; $i < 1000000; $i++) $a[$i] = array("hello"); echo memory_get_usage(true); if (in array($color, array(“red”, “yellow”, “green”)) { ... } Immutable Arrays (Неизменяемые массивы)
  • 17.
    Copyright - ©All rights reserved. Zend Technologies, Inc.17 zval (object/PHP 5) handlers zend_class_entry *ce typerefcount is_ref unused zval *propertyN HashTable *guards 0 7 8 31 32 63 handle ... ... ... HashTable *properies zval *property1 ... zval zval HEAP OBJECT STORE
  • 18.
    Copyright - ©All rights reserved. Zend Technologies, Inc.18 zval (object/PHP 7) ● IS_OBJ_DTOR_CALLED ● IS_OBJ_FREE_CALLED ● IS_OBJ_USE_GUARDS ● IS_OBJ_HAS_GUARDS flags value type reserved zend_class_entry *ce typerefcount flags gc_info zend_object_handlers *handlers HashTable *properies ... zval property_N zval property1 HashTable *guards (optional) 0 7 8 31 32 63
  • 19.
    Copyright - ©All rights reserved. Zend Technologies, Inc.19 zval (reference) flags value type reserved typerefcount flags gc_info zval val 0 7 8 31 32 63
  • 20.
    Copyright - ©All rights reserved. Zend Technologies, Inc.20 HashTable (PHP 5.*) nKeyLenght hash_val Bucket pData pDataPtr pListNext pListPrev pNext pPrev arKey pInternalPointer nTableSize nNextFreeElement nTableMask nNumOfElem pListHead pListTail arBuckets pDestructor HashTable nKeyLenght hash_val Bucket pData pDataPtr pListNext pListPrev pNext pPrev arKey type value zval Bucket* Bucket* ... Bucket* «hello»
  • 21.
    Copyright - ©All rights reserved. Zend Technologies, Inc.21 HashTable (PHP 7) Bucket index N ... Bucket index 0 key hash_val Bucket 0 val ... key hash_val Bucket N val gc flags arData nTableMask nNumUsed nNumOfElem nNextFreeElement HashTable/zend_array nInternalPtrnTableSize pDestructor string, rc=1 «hello»
  • 22.
    Copyright - ©All rights reserved. Zend Technologies, Inc.22 HashTable ● Размер HashTable уменьшен с 72 до 56 bytes ● Размер каждого Bucket-а уменьшен с 72 до 32 bytes ● Пространство выделяется под все Bucket-ы сразу ● Bucket.key теперь указатель на zend_string и не должен копироваться (достаточно увеличения счетчика ссылок) ● Значения элементов массива (zval) встроены в Bucket-ы и не требуют выделения памяти ● Улучшена “data locality” => меньше промахов в кашах CPU
  • 23.
    Copyright - ©All rights reserved. Zend Technologies, Inc.23 zval (IS_BOOL -> IS_FALSE + IS_TRUE) ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMP|VAR|CV, ANY) { long ret; zval *val = GET_OP1_ZVAL_PTR(BP_VAR_R); if (Z_TYPE_P(val) == IS_BOOL)) { ret = Z_LVAL_P(val); } else { ret = i_zend_is_true(val TSRMLS_CC); FREE_OP1(); CHECK_EXCEPTION(); } if (!ret) { ZEND_VM_SET_OPCODE( opline->op2.jmp_addr); ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); } ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMP|VAR|CV, ANY) { zval *val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); if (Z_TYPE_P(val) == IS_TRUE) { ZEND_VM_SET_OPCODE(opline + 1); ZEND_VM_CONTINUE(); } else if (Z_TYPE_P(val) <= IS_TRUE) { ZEND_VM_SET_OPCODE(opline->op2.jmp_addr); ZEND_VM_CONTINUE(); } if (i_zend_is_true(val TSRMLS_CC)) { opline++; } else { opline = opline->op2.jmp_addr; } FREE_OP1(); ZEND_VM_JMP(opline); } type check value read value check type check slow path slow path
  • 24.
    Copyright - ©All rights reserved. Zend Technologies, Inc.24 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) ... ... ...
  • 25.
    Copyright - ©All rights reserved. Zend Technologies, Inc.25 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) ... ... int(3), rc=1 HEAP Arg1: Arg2:
  • 26.
    Copyright - ©All rights reserved. Zend Technologies, Inc.26 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) ... int(3), rc=1 int(5), rc=1 HEAP Arg1: Arg2:
  • 27.
    Copyright - ©All rights reserved. Zend Technologies, Inc.27 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) CALL FRAME ... ... ... ... int(3), rc=1 int(5), rc=1 HEAP Arg1: Arg2: $a: $b:
  • 28.
    Copyright - ©All rights reserved. Zend Technologies, Inc.28 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) CALL FRAME ... ... ... int(3), rc=2 int(5), rc=1 HEAP Arg1: Arg2: $a: $b:
  • 29.
    Copyright - ©All rights reserved. Zend Technologies, Inc.29 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) CALL FRAME ... ... int(3), rc=2 int(5), rc=2 HEAP Arg1: Arg2: $a: $b:
  • 30.
    Copyright - ©All rights reserved. Zend Technologies, Inc.30 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) CALL FRAME int(8) ... int(3), rc=2 int(5), rc=2 HEAP Arg1: Arg2: $a: $b:
  • 31.
    Copyright - ©All rights reserved. Zend Technologies, Inc.31 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) CALL FRAME int(8) ... int(3), rc=2 int(5), rc=2 HEAP Arg1: Arg2: $a: $b:
  • 32.
    Copyright - ©All rights reserved. Zend Technologies, Inc.32 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) ... ... ...
  • 33.
    Copyright - ©All rights reserved. Zend Technologies, Inc.33 VM Calling Convention (PHP 7) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (zvals) ...SEND_VAL 3 SEND_VAL 5 DO_FCALL RETURN null INIT_FCALL “foo”/2 new instruction embedded zvals instead of pointers
  • 34.
    Copyright - ©All rights reserved. Zend Technologies, Inc.34 VM Calling Convention (PHP 7) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (zvals) CALL FRAME ... ... ... ...SEND_VAL 3 SEND_VAL 5 DO_FCALL RETURN null INIT_FCALL “foo”/2 Arg1: Arg2:
  • 35.
    Copyright - ©All rights reserved. Zend Technologies, Inc.35 VM Calling Convention (PHP 7) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (zvals) CALL FRAME int(3) ... ... ...SEND_VAL 3 SEND_VAL 5 DO_FCALL RETURN null INIT_FCALL “foo”/2 Arg1: Arg2:
  • 36.
    Copyright - ©All rights reserved. Zend Technologies, Inc.36 VM Calling Convention (PHP 7) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (zvals) CALL FRAME int(3) int(5) ... ...SEND_VAL 3 SEND_VAL 5 DO_FCALL RETURN null INIT_FCALL “foo”/2 Arg1: Arg2:
  • 37.
    Copyright - ©All rights reserved. Zend Technologies, Inc.37 VM Calling Convention (PHP 7) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (zvals) CALL FRAME int(3) int(5) ... ...SEND_VAL 3 SEND_VAL 5 DO_FCALL RETURN null INIT_FCALL “foo”/2 skip first 2 instructions Arg1, $a: Arg2, $b: local variables already in-place
  • 38.
    Copyright - ©All rights reserved. Zend Technologies, Inc.38 VM Calling Convention (PHP 7) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (zvals) CALL FRAME int(3) int(5) int(8) ...SEND_VAL 3 SEND_VAL 5 DO_FCALL RETURN null INIT_FCALL “foo”/2 Arg1, $a: Arg2, $b:
  • 39.
    Copyright - ©All rights reserved. Zend Technologies, Inc.39 VM Calling Convention (PHP 7) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (zvals) CALL FRAME int(3) int(5) int(8) ...SEND_VAL 3 SEND_VAL 5 DO_FCALL RETURN null INIT_FCALL “foo”/2 Arg1, $a: Arg2, $b:
  • 40.
    Copyright - ©All rights reserved. Zend Technologies, Inc.40 VM Calling Convention (PHP 7) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (zvals) ...SEND_VAL 3 SEND_VAL 5 DO_FCALL RETURN null INIT_FCALL “foo”/2 NOTE: ● func_get_arg*() changed behavior ● function foo($_, $_) {} is not allowed
  • 41.
    Copyright - ©All rights reserved. Zend Technologies, Inc.41 Новый менеджер памяти ● В PHP 5 менеджмент памяти потребляет более 20% процессорного времени (на Wordpress) ● Новый ММ отказался от алгоритмов dlmalloc и перешел на что-то напоминающее jemalloc ● Уменьшены издержки памяти на служебную информацию ● Использование поиска по битовой маске вместо обхода списков и деревьев ● Лучшее использование кэшей CPU ● Специализация под часто используемые размеры блоков ● Полностью прозрачная реализация ● Накладные расходы ММ уменьшены до 5%
  • 42.
    Copyright - ©All rights reserved. Zend Technologies, Inc.42 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za|b", &value, &array, &strict) == FAILURE) { return; } ZEND_PARSE_PARAMETERS_START(3, 2) Z_PARAM_ZVAL(value) Z_PARAM_ARRAY(array) Z_PARAM_OPTIONAL Z_PARAM_BOOL(strict) ZEND_PARSE_PARAMETERS_END(); Быстрое API для разбора параметров ● В PHP 5 5% времени тратится на разбор параметров внутренних функций ● Для некоторых простых функций время на разбор параметров составляет более 90%
  • 43.
    Copyright - ©All rights reserved. Zend Technologies, Inc.43 Множество мелких усовершенствований ● Новые инструкции VM (конкатенация строк, специализация, супер-инструкции) ● Некоторые внутренние функции превращены в инструкции VM (strlen, is_int) ● Использование регистров CPU под регистры VM (IP и FP) ● Новый API для итерации по HashTable ● Оптимизация функций дублирования и удаления массивов ● Использования счетчиков ссылок вместо копирования везде где можно ● PCRE JIT ● Оптимизация внутренних функций ● Оптимизация serialize() ● Уменьшение размера кода и обрабатываемых данных
  • 44.
    Copyright - ©All rights reserved. Zend Technologies, Inc.44 Откуда ускорение? (WordPress/PHP 5.6)
  • 45.
    Copyright - ©All rights reserved. Zend Technologies, Inc.45 Откуда ускорение? (WordPress/PHP 7.0)
  • 46.
    Copyright - ©All rights reserved. Zend Technologies, Inc.46 PHP 5.6 PHP 7.0 улучшение VM 27% 19,494M 46% 9,005M 2 раза alloc 22% 15,575M 5% 905M 17 раз hash 13% 9,590M 13% 2.450M 4 раза libc 6% 4.585M 8% 1,598M 3 раза Total: 100% 70,798M 100% 19,462M 3.5 раз Откуда ускорение? (WordPress)
  • 47.
    Copyright - ©All rights reserved. Zend Technologies, Inc.47 Производительность PHP 7 Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov 0 5 10 15 20 25 30 24.04 24.04 24.04 22.64 18.62 16.37 15.28 14.86 14.16 13.83 13.56 13.28 12.58 12.39 11.67 11.48 11.08 11.04 10.88 10.69 10.5 10.4 10.4 sec ● Время исполнения 1000 запросов к Wordpress-3.6.0 ● php-cgi -T 1000 /.../wordpress/index.php > /dev/null
  • 48.
    Copyright - ©All rights reserved. Zend Technologies, Inc.48 PHP-5.6 PHP-7.0.0 разница HHVM-3.10.0 разница ZF1 Hello 1,144 2,557 124% 1,526 40% ZF2 Test 258 614 138% 390 36% Magento (home) 43 73 70% 65 11% SugarCRM (login) 134 307 129% 204 34% Laravel 304 553 82% 447 19% Drupal 7 192 372 94% 331 11% Drupal 8 428 655 94% 526 11% Mediawiki 46 79 72% 85 -8% Wordpress-4.1 92 222 82% 210 19% PHP 5.6 против PHP 7.0 против HHVM
  • 49.
    Copyright - ©All rights reserved. Zend Technologies, Inc.49 PHP 5.6 против PHP 7.0 против HHVM ZF1 Hello ZF2 Test Magento (home) SugarCRM (login) Laravel Drupal 7 Drupal 8 Mediawiki Wordpress-4.1 0 0.5 1 1.5 2 2.5 3 PHP 5.6 PHP 7.0 HHVM 3.10.0
  • 50.
    Copyright - ©All rights reserved. Zend Technologies, Inc.50 PHP 5 против PHP 7 против HHVM (версия Facebook)
  • 51.
    Copyright - ©All rights reserved. Zend Technologies, Inc.51 Проверка в деле
  • 52.
    Copyright - ©All rights reserved. Zend Technologies, Inc.52 Badoo перешли на PHP 7.0 и сэкономили $1M
  • 53.
    Copyright - ©All rights reserved. Zend Technologies, Inc.53 Badoo перешли на PHP 7.0 и сэкономили $1M
  • 54.
    Copyright - ©All rights reserved. Zend Technologies, Inc.54 Badoo перешли на PHP 7.0 и сэкономили $1M
  • 55.
    Copyright - ©All rights reserved. Zend Technologies, Inc.55 Что дальше? ● Попробуем обойтись без революционных внутренних изменений ● Анализатор потоков данных и глобальный оптимизатор для байт-кода PHP ● Вывод типов ● Использование типизированных инструкций (ADD, ADD_LONG, ADD_DOUBLE) ● Экстра-специализация инструкций (DO_FCALL_RET, DO_FCALL_NORET) ● Оптимизация диспетчеризации виртуальных инструкций (надо менять GCC) ● Надо что-то делать с CALL/RETURN. ● И еще раз JIT?
  • 56.
    Copyright - ©All rights reserved. Zend Technologies, Inc.56 Что дальше? 0 2 4 6 8 10 12 14 12.68 12.54 4.68 4.2 2.91 2.18 2.03 1.92 0.78 0.6 0.36 bench.php [sec] 4.4 5.0 - Jul 2004 5.1 - Nov 2005 5.2 - Nov 2006 5.3 - Nov 2009 5.4 - Mar 2012 5.5 - Jun 2013 5.6 - Aug 2014 7.0.0 - Dec 2015 7.1-dev Mar 2016 HHVM-3.12.1 secNext Step!
  • 57.
    Confidential - ©All rights reserved. Zend Technologies, Inc.57 Вопросы? Dmitry Stogov Principal Engineer at Zend Technologies @dstogov dmitry@zend.com www.zend.com