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

PHPの関数実行とその計測

sji
January 29, 2019

 PHPの関数実行とその計測

PHPカンファレンス福岡2019
https://www.youtube.com/watch?v=-WJG7R5bEvg

sji

January 29, 2019
Tweet

More Decks by sji

Other Decks in Programming

Transcript

  1. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 16/78 // 実際にはもう少し複雑 foreach ($op_array as $opline)

    { // 例: [ADD, [1, 2]] [$opcode, $operands] = $opline; $handler = $opcode_handlers[$opcode]; $handler($operands); }
  2. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 19/78 字句解析 字句解析 ↓ <?php function sum(int

    $a, int $b): int { return $a + $b; } echo sum(1, 2); T_OPEN_TAG T_FUNCTION T_STRING (T_STRING T_VARIABLE, T_STRING T_VARIABLE): T_STRING { T_RETURN T_VARIABLE + T_VARIABLE; } T_ECHO T_STRING(T_LNUMBER, T_LNUMBER);
  3. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 21/78 構文解析(構文規則一部) 構文解析(構文規則一部) top_statement: function_declaration_statement function_declaration_statement: function

    returns_ref T_STRING '(' parameter_list ')' return_type '{' inner_statement_list '}' returns_ref: /* empty */ | '&' parameter_list: non_empty_parameter_list | /* empty */ non_empty_parameter_list: parameter | non_empty_parameter_list ',' parameter
  4. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 22/78 構文解析(構文規則一部) 構文解析(構文規則一部) parameter: optional_type is_reference is_variadic

    T_VARIABLE | optional_type is_reference is_variadic T_VARIABLE '=' expr optional_type: /* empty */ | type_expr type_expr: type | '?' type type: T_ARRAY | T_CALLABLE | name
  5. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 23/78 構文解析(構文規則一部) 構文解析(構文規則一部) name: namespace_name | T_NAMESPACE

    T_NS_SEPARATOR namespace_name | T_NS_SEPARATOR namespace_name namespace_name: T_STRING | namespace_name T_NS_SEPARATOR T_STRING return_type: /* empty */ | ':' type_expr ;
  6. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 26/78 構文解析(具象構文木) 構文解析(具象構文木) top_statement_list top_statement function_declaration_statement statement

    function return_type T_FUNCTION : T_STRING parameter_list ( ) nom_empty_parameter_list parameter parameter , optional_type T_VARIABLE type_expr type name namespace_name T_STRING optional_type T_VARIABLE type_expr type name namespace_name T_STRING type name namespace_name type_expr T_STRING inner_statement_list この先省略 この先省略 top_statement
  7. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 27/78 構文解析(AST) 構文解析(AST) AST_STMT_LIST AST_FUNC_DECL AST_ECHO AST_PARAM_LIST

    AST_STMT_LIST AST_TYPE AST_PARAM AST_PARAM AST_TYPE a AST_TYPE b AST_RETURN AST_BINARY_OP AST_VAR AST_VAR a b AST_CALL AST_NAME AST_ARG_LIST 1 2
  8. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 31/78 生成されるコード 生成されるコード $_main: INIT_FCALL 2 128

    string("sum") SEND_VAL int(1) 1 SEND_VAL int(2) 2 V0 = DO_UCALL ECHO V0 RETURN int(1) sum: CV0($a) = RECV 1 CV1($b) = RECV 2 T2 = ADD CV0($a) CV1($b) VERIFY_RETURN_TYPE T2 RETURN T2 VERIFY_RETURN_TYPE RETURN null
  9. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 35/78 関数呼び出しのオペコード 関数呼び出しのオペコード $_main: INIT_FCALL 2 128

    string("sum") SEND_VAL int(1) 1 SEND_VAL int(2) 2 V0 = DO_UCALL ECHO V0 RETURN int(1) sum: CV0($a) = RECV 1 CV1($b) = RECV 2 T2 = ADD CV0($a) CV1($b) VERIFY_RETURN_TYPE T2 RETURN T2 VERIFY_RETURN_TYPE RETURN null
  10. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 41/78 ZendEngineでの関数実行まとめ ZendEngineでの関数実行まとめ PHP コードは関数の集まり、一見ないように見えても 関数はオペコードの集まり PHP

    コードはオペコードにコンパイルされる VM はメモリ上にその時々の状態を持つ ZendEngine の挙動は拡張等でカスタマイズできる
  11. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 46/78 原始的計測 原始的計測 <?php function sum(int $a,

    int $b): int { return $a + $b; } $start = microtime(true); $result = sum(1, 2); $end = microtime(true) - $start; }
  12. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 49/78 Pro ler とは Pro ler とは

    性能解析のためのツール プログラムの各処理の実行性能を収集 統計情報を出力
  13. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 53/78 フック方式の仕組み フック方式の仕組み op_array を実行する zend_execute_ex() は実際には関数ポインタ

    拡張から以下のような処理へ差し替える 開始時刻を取得 差し替え前の zend_execute_ex() を呼び出す 終了時刻を取得 「呼び出し元関数名 + 関数名」をキーにした連想配列へ全呼 び出しを記録
  14. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 55/78 xhprof xhprof Facebook 製の拡張 HHVM 移行で

    PHP7 未対応のまま捨てられた 関数フック方式 全関数呼び出しをフック black re や tideways 等に派生 xdebug のより軽いのがウリ
  15. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 58/78 tideways tideways 元は xhprof からの派生プロファイラ 区間計測機能を持つ

    現在は xhprof ベースではなく、0 からリライトされたクローズドソー スの拡張に xhprof 互換機能のみ切り出した tideways_xhprof が OSS に xhprof 互換の無料で使えるプロファイラの中でもよくメンテされて る
  16. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 63/78 PHP8 の JIT PHP8 の JIT

    来年末に PHP8 リリース JIT が入る I/O バウンドな処理にはあまり関係ないが、PHP コード自体は速く なる VM の実行方式が変わって zend_execute_ex() フックが効かなくな るかも AST 操作等で自動で計測処理を仕込む手もあるが、オーバーヘッ ド問題大きくなる
  17. 2019/6/29 reveal.js localhost:8000/?print-pdf/#/ 66/78 サンプリング方式の仕組み サンプリング方式の仕組み 計測対象と平行動作するプログラムが VM の状態をサンプリング して監視

    ExecutorGlobals や VM の呼び出しスタック、実行中の命令位置 など サンプリングしたタイミングでよく実行されている箇所が重い箇所