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

HHVM Hack

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on. →

HHVM Hack

HHVM Hack recipe

Avatar for Masaaki Yonebayashi

Masaaki Yonebayashi

June 01, 2014

Other Decks in Programming

Transcript

  1. Hack Hack とはFacebook がリリー スしたPHP と互換性を持つ HHVM(Hip Hop Virtual Machine

    for PHP) 向けの開発言語 Facebook のサイトは2013 年以降PHP からHack へ移行 Facebook での実績 特長 Nullable, Generics, etc... http://hacklang.org/      
  2. Hack Hack とはFacebook がリリー スしたPHP と互換性を持つ HHVM(Hip Hop Virtual Machine

    for PHP) 向けの開発言語 Facebook のサイトは2013 年以降PHP からHack へ移行 Facebook での実績 特長 Nullable, Generics, etc... http://hacklang.org/ Summary PHP の代替になる新しいプログラミング言語
  3. HHVM HHVM(HipHop Virtual Machine) とはFacebook が開発・ 公開し ているC++ で実装されたJIT コンパイラPHP

    実行環境 JIT コンパイル -> 高速動作 Hack を動作させる唯一のVM FastCGI インター フェー ス仕様でnginx, Apache と動作 最新 version (2014/05/30 現在) http://hhvm.org/ $ hhvm --version HipHop VM 3.2.0-dev (rel)  
  4. HHVM HHVM(HipHop Virtual Machine) とはFacebook が開発・ 公開し ているC++ で実装されたJIT コンパイラPHP

    実行環境 JIT コンパイル -> 高速動作 Hack を動作させる唯一のVM FastCGI インター フェー ス仕様でnginx, Apache と動作 最新 version (2014/05/30 現在) http://hhvm.org/ $ hhvm --version HipHop VM 3.2.0-dev (rel) Summary PHP とHack を動作させるVM
  5. Hack Features Type Annotations 静的型付けがあり関数の引数や戻り値に明示的に型を宣 言することが可能 class AnnotatedClass { public

    int $i = 10; private string $str = "STRING"; protected array $arr = array(1, 2); } function return_int_func(bool $flg): int { return 100; }
  6. Hack Features Nullable null を許容するかどうかを? で指定可能 function nullable_arg_func(?string $name) :

    string { if ($name === null) return "name is null"; return "Hello " . $name; } function null_ng_arg_func(string $name) : string { return "Hello " . $name; } nullable_arg_func(null); null_ng_arg_func(null); // エラー発生 実行結果 $ hhvm examples.php Fatal error: Argument 1 passed to null_ng_arg_func() must be an instance of string, null given in /home/yone098/examples.php on line 10
  7. Hack Features Generics C++, Java, C# のような Genrics が利用可能 class

    Dog<T> { private ?T $name; public function __construct(T $name) { $this->name = $name; } public function get_name() : T { return $this->name; } } $dog = new Dog("garsue"); echo("dog->get_name()=" . $dog->get_name() . "\n"); $map = Map<string, int> { "a" => 1, "b" => 2 }; var_dump($map); 実行結果 dog->get_name=garsue object(HH\Map)#2 (2) { ["a"]=> int(1) ["b"]=>int(2)}
  8. Hack Features Collections Hack では Vector,Map,Set,Pair というCollections が利用 可能 $vector

    = Vector<int> { 100, 200, 300, 400 }; $vector[] = 700; // 追加 $vector[0] = 111; // 上書き $vector->removeKey(2); foreach ($vector as $v) { echo $v . "\n"; } $map = Map<string, long> {"a" => 100, "b" => 200, "c" => 300}; $map["d"] = 400; echo "map->get(\"b\") = ". $map->get("b") . "\n"; var_dump($map->contains("a")); // map filterWithKey $map_filter = $map->filterWithKey(function($k, $v) { return ($k === "b" || $k === "c"); }); var_dump($map_filter);
  9. Hack Features Type Aliasing Hack では,type およびnewtype の宣言で既存の型に別名を つけることが可能。 type

    user_id = int; // 引数の型は user_id function get_user_name(user_id $user_id): string { return "mopemope"; } newtype password = string; // 引数の型は password function login(user_id $user_id, password $password): bool { return true; }
  10. Hack Features Variable Number of Arguments Hack では可変長引数を ... と明示的に指定可能

    function test_many_args(int $num, ...): void { echo "num:" . $num . "\n"; foreach (func_get_args() as $e) { var_dump($e); } } test_many_args(100, "garsue", 1, array(), 3.14); 実行結果 num:100 int(100) string(6) "garsue" int(1) array(0) { } object(Yone)#8 (0) { } float(3.14)
  11. Tool Debugger 起動:hhvm -m debug ファイル名 ブレー クポイント:break 関数名 ステップ実行:step

    確認:print 変数名 現在: * Break at loop() on line 3 of /home/yone098/debug.php 2 function loop() : void { 3* for ($i = 1; $i <= 3; $i++) { 4 $sum += $i; hphpd> print $sum 1 demo
  12. Tool Debugger variable (Web application) hphpd> variable $argv = Array()

    $_FILES = Array() $_SERVER = Array([XDG_SESSION_ID] => "4", [USER] => "yone098", [SSH_TTY] => ... $_GET = Array() $_COOKIE = Array() $argc = 0 $_REQUEST = Array() $_POST = Array()
  13. Tool hh_client 不正な箇所がある場合に行番号と内容を表示 bad.php <?hh function bad_func() : int {

    return "Hello, BpStudy#81"; } bad_func();   実行結果 $ hh_client /home/yone098/bad.php:3:10,28: Invalid return type /home/yone098/bad.php:2:23,25: This is an int /home/yone098/bad.php:3:10,28: It is incompatible with a string プロジェクトのルー トフォルダに .hhconfig ファイルを設置 しチェックを行うのがベスト
  14. Tool fastcgi apache, nginx に対して fastcgi 設定を自動で行う /usr/share/hhvm/install_fastcgi.sh /usr/share/hhvm/uninstall_factcgi.sh apache,

    nginx をインストー ルしたあとにシェルを実行する ことですんなり HHVM が稼働します 当初は自前で設定する必要があったため即動かす事が容易 ではなかった
  15. WebApplication First step phpinfo を確認する HHVM が正常に稼働していれば画面には HipHop とだけ 表示されます

    503 エラー などが出る場合は、fastcgi の設定が間違って いるか HHVM が起動していない可能性があります check.php <?hh phpinfo(); 実行結果 HipHop
  16. WebApplication はまりどころ configrations HHVM 2 系の際は /etc/hhvm/php.ini および /etc/hhvm/server.ini の設定が有効

    ( 厳密には以前は server.hdf) HHVM 3 系の場合は php include_path の設定が効かない ため実行時に設定する必要がある <?hh echo 'include_path[' . get_include_path() . '][' . ini_get('include_path') . "]<br/>\n"; ini_set('include_path', '/usr/lib/Smarty-3.1.18/libs' . PATH_SEPARATOR . ini_get('include_path')); require_once('Smarty.class.php');
  17. WebApplication はまりどころ 実行時 <?hh echo でHTML に記載したものはまだ動かない <html> <body> <?php

    echo $user_name; ?> <hr/> <?hh echo $user_name; ?> <!-- これは動作しない --> </body> </html>
  18. Performance bench.php <?php function loop_test() { $sum = 0; for

    ($i = 0; $i < 1000000; $i++) { $sum += $i * 2; } } function main() { $startTime = microtime(true); loop_test(); $endTime = microtime(true); echo $endTime - $startTime . "[sec]\n"; // 再度実行 } main();
  19. Performance result php : hhvm = 1 : 10 yone098@ubuntu-docker:~/work$

    hhvm bench.php 0.012295007705688[sec] 0.010360956192017[sec] yone098@ubuntu-docker:~/work$ hhvm bench.php 0.0089778900146484[sec] 0.011922836303711[sec] yone098@ubuntu-docker:~/work$ php bench.php 0.10031509399414[sec] 0.098863124847412[sec] yone098@ubuntu-docker:~/work$ php bench.php 0.09879994392395[sec] 0.099910974502563[sec]
  20. Performance wordpress ab wordpress nginx + php-fpm Requests per second:

    19.53 [#/sec] (mean) Time per request: 2560.771 [ms] (mean) Time per request: 51.215 [ms] (mean, across all concurrent requests) Transfer rate: 154.85 [Kbytes/sec] received wordpress nginx + fastcgi + hhvm Requests per second: 42.97 [#/sec] (mean) Time per request: 1163.692 [ms] (mean) Time per request: 23.274 [ms] (mean, across all concurrent requests) Transfer rate: 340.33 [Kbytes/sec] received
  21. HHVM Extensions HHVM の拡張機能であり C++ の既存資産を生かす事が可能 HNI (HHVM Native Interface)

    と呼ばれるHack の記法を使う 必要ファイル config.cmake ext_hnifib.php (HNI で登録) hnifib.cpp (HHVM_XX で登録) build (hphpize コマンド) exec (-vDinamicExtensions.0= ライブラリ.so) 本家のはそのままじゃ動かない https://github.com/facebook/hhvm/wiki/Extension-API https://github.com/yone098/hhvm-extensions-examples
  22. HHVM Extensions sample.cpp HNI 用 include HHVM_FUNCTION で定義, HHVM_FE で登録

    Extension クラスを継承 #include "hphp/runtime/base/base-includes.h" namespace HPHP { static int64_t HHVM_FUNCTION(hni_fib, int64_t n) { if (n <= 2) return 1; return HPHP::f_hni_fib(n - 2) + HPHP::f_hni_fib(n - 1); } static class HnifibExtension : public Extension { public: HnifibExtension() : Extension("hnifib") {} virtual void moduleInit() { HHVM_FE(hni_fib); loadSystemlib(); } } s_hnifib_extension; HHVM_GET_MODULE(sample) }
  23. HHVM Extensions Performance <?php function fib($n) { if ($n <=

    2) return 1; return fib($n - 2) + fib($n - 1); } for ($i = 1; $i <= 20; $i++) echo(fib($i) . " "); result HNI 速い! > hhvm > php $ php fib.php 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 0.013734102249146[sec] $ hhvm fib.php 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 0.0083420276641846[sec] $ ./run.sh 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 0.0031008720397949[sec]
  24. PHP2HHVM PHP ファイルをそのまま使う HHVM のみ利用する ( お勧め) PHP ファイルを Hack

    に移行 ソー スの先頭は一括置換 (<?PHP から <?hh ) 関数の引数・ 戻り値に型を明示的に指定 null を許容する場合のみ明示的に ? を指定 積極的に Collection を利用する ( 速度よびメモリ使用量削 減) hh_client にてチェックを行う