今日、スカラーとストライドの使用PHP7のct型はパフォーマンスを向上させません。
PHP7にはJITコンパイラがありません。
将来、PHPがJITコンパイラを取得する場合、追加の型情報で実行できる最適化を想像するのは難しくありません。
JITを使用しない最適化については、スカラー型はほんの一部に役立ちます。
のは、次のコードを見てみましょう:
<?php
function (int $a, int $b) : int {
return $a + $b;
}
?>
これはそのためのZendによって生成されたコードです:
function name: {closure}
L2-4 {closure}() /usr/src/scalar.php - 0x7fd6b30ef100 + 7 ops
L2 #0 RECV 1 $a
L2 #1 RECV 2 $b
L3 #2 ADD $a $b ~0
L3 #3 VERIFY_RETURN_TYPE ~0
L3 #4 RETURN ~0
L4 #5 VERIFY_RETURN_TYPE
L4 #6 RETURN null
ZEND_RECV
は、受信したパラメータの検証および強制を入力し実行オペコードです。次のオペコードはZEND_ADD
です:
ZEND_VM_HANDLER(1, ZEND_ADD, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
zval *op1, *op2, *result;
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
result = EX_VAR(opline->result.var);
fast_long_add_function(result, op1, op2);
ZEND_VM_NEXT_OPCODE();
} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
result = EX_VAR(opline->result.var);
ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
ZEND_VM_NEXT_OPCODE();
}
} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
result = EX_VAR(opline->result.var);
ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
ZEND_VM_NEXT_OPCODE();
} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
result = EX_VAR(opline->result.var);
ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
ZEND_VM_NEXT_OPCODE();
}
}
SAVE_OPLINE();
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
}
if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) {
op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
}
add_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
そのコードのいずれかが、あなたはそれがかなり複雑だということを見ることができないものを理解せず。
そこでターゲットを完全ZEND_RECV
を省略し、paramsはの種類が知られているので、または分岐(ガードを越えて)任意のチェックを実行する必要はないZEND_ADD_INT_INT
とZEND_ADD
を交換することになります。
これらを省略してZEND_ADD_INT_INT
を指定するには、コンパイル時に$a
と$b
のタイプを確実に推測できる必要があります。例えば、$a
と$b
のようなコンパイル時の推論は、リテラルの整数または定数です。
文字どおりyesterday、PHP 7.1には本当に似たようなものがあります:ZEND_ADD
のようないくつかの高周波オペコード用の型指定ハンドラがあります。 Opcacheは、それはいくつかのケースでは、アレイ内の変数の型を推論し、種類の特定のハンドラを使用するように、通常のZEND_ADD
を使用するために生成されたオペコードを変更することさえできます、いくつかの変数の型を推論することができます:
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_ADD, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG_NO_OVERFLOW, 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_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2));
ZEND_VM_NEXT_OPCODE();
}
繰り返しますが、何が起こっているのか理解していなければ、これはであり、実行するのがさらに簡単です。です。
これらの最適化は非常にクールですが、最も効果的で最も興味深い最適化は、PHPにJITがある場合に発生します。
スカラー型ヒントの潜在的にパフォーマンスを向上させる効果の1つは、型キャストが早期に発生するように強制されるため、後続のキャスト数を減らす可能性があります。 – NikiC