目次
背景
あなたならどうしますか?
PHP の高速化
より高速な仮想マシン
PHP 言語の実装は、仮想マシンの実装と同じくらい簡単ではありません。PHP 言語自体にもさまざまな拡張機能が含まれており、これらの拡張機能は、使用できるさまざまな機能を実装するために絶えず機能します。 PHP コードを分析すると、空白行のコメントを除いた C コードには 80 万行以上あることがわかります。そして、Zend エンジンの部分がいくつあると思いますか。行数は 100,000 行弱です。
インタプリタの実装
ホームページ バックエンド開発 PHPチュートリアル HHVM はどのように PHP のパフォーマンスを向上させますか?

HHVM はどのように PHP のパフォーマンスを向上させますか?

Jul 27, 2016 pm 04:56 PM

引用

背景

HHVM は Facebook によって開発された高性能 PHP 仮想マシンで、公式のものよりも 9 倍高速であると主張されています。非常に興味があったので、時間をかけて簡単に学習し、この記事にまとめました。 2 つの質問に答えることができます:

  • HHVM は信頼できますか?製品に使用できますか?
  • 公式の PHP よりもはるかに速いのはなぜですか?どのように最適化されていますか?

あなたならどうしますか?

HHVM の実装原則について説明する前に、自分の立場になって考えてみましょう。PHP で書かれた Web サイトでパフォーマンスの問題が発生したとします。分析の結果、リソースの大部分が PHP で消費されていることがわかりました。どのように最適化しますか。 PHPのパフォーマンスは?

たとえば、いくつかの方法があります:

  • オプション 1、Java、C++、Go など、よりパフォーマンスの高い言語に移行します。
  • オプション 2、RPC を通じて関数を分離し、他の言語で実装することで、PHP が実行できる処理が少なくなります。たとえば、Twitter は多くのビジネス ロジックを Scala に組み込み、フロントエンドの Rails はプレゼンテーションのみを担当します。
  • オプション 3、PHP 拡張機能を作成し、パフォーマンスのボトルネックで C/C++ に切り替えます。
  • オプション 4、PHP のパフォーマンスを最適化します。

オプション 1 は、10 年前、Netscape の例を挙げて、特に Facebook のような複雑なビジネス ロジックを備えた製品については、PHP コードが多すぎると警告しました。行数は 2,000 万と言われています ([PHP on the Metal with HHVM] から引用) 変更のコストはおそらく仮想マシンを作成するよりも大きく、数千人のチームにとってはゼロから学習することは受け入れられません。

オプション 2 は最も安全なソリューションであり、段階的に移行できます。実際、Facebook もこの点で熱心に取り組んでおり、初期の頃から Facebook 内で主に使用されているもう 1 つの言語は C++ です。これは、Thrift コードで確認できます。他の言語での実装は非常に粗雑で、運用環境では使用できないためです。

現在、Facebook では PHP:C++ が 9:1 から 7:3 に増加したと言われており、Andrei Alexandrescu の存在も相まって Facebook では C++ の人気が高まっていますが、これでは問題の一部しか解決できません。結局のところ、C++ の開発コストは PHP よりもはるかに高く、頻繁に変更される場所での使用には適しておらず、RPC 呼び出しが多すぎるとパフォーマンスに重大な影響を及ぼします。

オプション 3 は良さそうですが、実際に実装するのは困難です。一般的に、パフォーマンスのボトルネックはそれほど重大ではなく、主に PHP 拡張機能の開発コストが高くなります。通常、これは公開アプリケーションでのみ使用され、あまり変更されていない基本ライブラリに基づいているため、このソリューションでは多くの問題を解決できません。

最初の 3 つの解決策では問題をうまく解決できないことがわかり、Facebook は実際には PHP 自体の最適化を検討するしかありません。

PHP の高速化

PHPを最適化したいのですが、どのように最適化すればよいでしょうか?私の意見では、いくつかの方法があります:

  • オプション 1、PHP 言語レベルでの最適化。
  • オプション 2、PHP の公式実装 (つまり、Zend) を最適化します。
  • オプション 3、PHP を他の言語のバイトコード (バイトコード) にコンパイルし、他の言語の仮想マシン (JVM など) を利用して実行します。
  • オプション 4、PHP を C/C++ に変換し、ローカル コードにコンパイルします。
  • オプション 5、より高速な PHP 仮想マシンを開発します。

PHP 言語レベルの最適化は最もシンプルで実現可能です。もちろん Facebook もそれを考えており、パフォーマンスのボトルネックを特定するのに非常に役立つ XHProf のようなパフォーマンス分析ツールも開発しました。

ただし、XHProf は依然として Facebook の問題をうまく解決できていないため、引き続き検討を続けます。次はオプション 2 です。簡単に言うと、Zend の実行プロセスは、PHP をオペコードにコンパイルする部分と、オペコードを実行する部分の 2 つの部分に分けることができるため、最適化が行われます。 Zend それはこの 2 つの側面から考えることができます。

オペコードの最適化は一般的な方法であり、PHP の繰り返しの解析を回避でき、また、Zend Optimizer Plus などの静的なコンパイルの最適化も行うことができます。ただし、PHP 言語の動的な性質のため、この最適化方法は限定的で楽観的です。パフォーマンスは 20% しか向上しないと推定されています。もう 1 つの考慮事項は、レジスタベースのアプローチなど、オペコード アーキテクチャ自体を最適化することですが、このアプローチでは変更に多大な労力が必要であり、パフォーマンスの向上は特に明らかではありません (おそらく 30%?)。高くありません。

もう 1 つの方法は、オペコードの実行を最適化することです。まず、Zend のインタプリタ (インタプリタとも呼ばれます) がオペコードを読み取った後、さまざまなオペコードに応じてさまざまな関数を呼び出します (実際には一部はスイッチですが、説明は便宜上簡略化しています)、この関数内でさまざまな言語関連の操作を実行します (興味がある場合は、書籍「PHP コアの徹底理解」を参照してください)。そのため、複雑なカプセル化やZend での間接呼び出しの説明として、このデバイスではすでに非常にうまく機能しています。

Zend の実行パフォーマンスを向上させたい場合は、実際には関数呼び出しにはオーバーヘッドがあるため、その原理は C の inline キーワードに似ています。この方法では、実行時に関連する関数が展開され、それらが順番に実行されます (単なる例えであり、実際の実装は異なります)。また、CPU パイプライン予測の失敗によって引き起こされる無駄も回避します。

さらに、JavaScriptCore や LuaJIT などのアセンブリを使用してインタープリターを実装することもできます。具体的な詳細については、Mike の説明を読むことをお勧めします。

しかし、これら 2 つのメソッドは変更するにはコストがかかりすぎ、特に下位互換性を確保するためには、1 つを書き直すよりもさらに困難です。これは、後で PHP の特性について説明するときにわかると思います。

高性能の仮想マシンを開発するのは簡単なことではありません。JVM が現在のパフォーマンスに達するまでに 10 年以上かかりました。では、これらの高性能の仮想マシンを PHP のパフォーマンスの最適化に直接使用できるでしょうか。これが選択肢3の考え方です。

実際、このソリューションは Quercus や IBM の P8 などによって長い間試みられてきましたが、Quercus はほとんど誰も使用されておらず、P8 も廃止されました。 Facebookもこの手法を調査しており、信憑性の低い噂も流れたが、実際にはFacebookは2011年に断念している。

オプション 3 は見た目は良いですが、実際の効果は理想的ではないため、多くの専門家 (マイクなど) によると、VM は常に特定の言語に対して最適化されており、他の言語では動的言語などの実装時に多くのボトルネックが発生します。メソッド呼び出しは Dart のドキュメントで紹介されており、Quercus のパフォーマンスは Zend+APC とそれほど変わらないと言われている ([The HipHop Compiler for PHP より]) ので、あまり意味はありません。

しかし、最近の Grall プロジェクトはかなり良くできていて、大きな成果を上げている言語もありますが、私はまだ Grall を勉強する時間がありません。なのでここでは判断できません。

次のステップはオプション 4 で、これはまさに HPHPc (HHVM の前身) が行うことです。原理は、PHP コードを C++ に変換し、それをローカル ファイルにコンパイルすることです。これは (事前に) AOT と見なすことができます。 ) メソッドについて コード変換の技術的な詳細については、論文「The HipHop Compiler for PHP」を参照してください。以下は概要を理解するために使用できる論文のスクリーンショットです。

このアプローチの最大の利点は、(VM と比較して) 実装が簡単で、多くのコンパイル最適化を行うことができることです (オフラインなので、遅くても問題ありません)。たとえば、上記のようになります。インタプリタを埋め込むコストは小さくないため、HPHPc は単純にこれらの構文をサポートしていません。

HHVM 是如何提升 PHP 性能的? HPHPc に加えて、2 つの同様のプロジェクトがあり、1 つは Roadsend で、もう 1 つは phc です。phc のアプローチは、PHP を C に変換してからコンパイルすることです。以下は、

を C コードに変換する例です。 - 1优化掉了,但它很难支持 PHP 中的很多动态的方法,如 eval()create_function()

file_get_contents($f)static php_fcall_info fgc_info;

php_fcall_info_init ("file_get_contents", &fgc_info);php_hash_find (LOCAL_ST, "f", 5863275, &fgc_info.params);<div class="blockcode">php_call_function (&fgc_info) ) ;<div id="code_LjU"><ol> <li>コードをコピー</li> <li> <li> <p> phc と言えば、2 年前に Facebook に phc のデモをしに行って、そこのエンジニアとコミュニケーションを取った結果、リリースされるやいなや人気が出た、と著者がブログで泣いたことがある。 4年間忙しかったが、今は未来が暗い。 。 。 </p> <p>Roadsend は保守されなくなりました。PHP のような動的言語の場合、このアプローチには多くの制限があり、オンラインにする際のファイルのデプロイメントは実際に 1G に達してしまいました。 </p> <p>PHP QB というプロジェクトもありますが、これは時間の都合上見ませんでした。おそらく似たようなものだと思います。 </p> <p>残された道は 1 つだけです。それは、より高速な PHP 仮想マシンを作成して、この暗い道を最後までやり遂げることです。Facebook が仮想マシンを構築すると最初に聞いたとき、あなたはそう思ったかもしれません。はあまりにも無茶苦茶でしたが、よく分析してみると実はこれしか方法がないことが分かります。 </p> <h2 id="より高速な仮想マシン">より高速な仮想マシン</h2> <p>HHVM のほうが速いのはなぜですか? JITのキーテクノロジーはさまざまなニュースで取り上げられていますが、実際のところ、JITは一振りするだけでパフォーマンスが向上する魔法の杖ではなく、JIT自体の運用にも時間がかかります。最も極端な例では、LuaJIT 2 のインタープリターは V8 の JIT よりも若干速いため、詳細な処理に絶対的なものはありません。 . HHVM の開発の歴史 それは継続的な最適化の歴史であり、HPHPc を少しずつ超えていることがわかります: </p> <img src="/static/imghw/default1.png" data-src="http://img.it-home.org/data/attachment/forum/2014pic/20140321154123_97.jpg" class="lazy" alt="HHVM 是如何提升 PHP 性能的?" style="max-width:90%" style="max-width:90%"> <p>Android 4.4 の新しい仮想マシン ART は AOT ソリューション (覚えていますか? 前述の HPHPc がこれです) を使用しており、結果は JIT を使用した以前の Dalvik の 2 倍高速であるため、必ずしも JIT が高速であるとは限りません。 AOTよりも。 </p> <p>したがって、このプロジェクトは非常に危険であり、強い心と忍耐力がなければ、Google は Python のパフォーマンスを向上させるために JIT を使用しようと考えていましたが、最終的には Python の使用は失敗しました。実際にはパフォーマンスの問題はありません (Google は以前、クロールを Python で記述していました [In The Plex を参照] が、それはすべて 1996 年のことです)。 </p> <p> Google と比較して、Facebook は明らかにモチベーションと決意が優れています。PHP は Facebook がこのプロジェクトに投資した専門家を見てみましょう (未完了)。 </p> <ul>Andrei Alexandrescu 氏、『Modern C++ Design』および『C++coding Standards』の著者、C++ 分野の誰もが認めるマスター<li> </li>Keith Adams は VMware のコア アーキテクチャを担当していました。当時、VMware は Intel との技術協力を行うために彼を単身派遣しました。これは彼が VMM の分野でどれだけの知識を持っていたかを証明しました<li>。 </li>Microsoft で .NET 仮想マシンの開発に参加し、JIT を改善した Drew Paroski 氏<li> </li>Jason Evans、Firefox のメモリ消費量を半分に削減する jemalloc を開発<li> </li>Sara Golemon、『PHP の拡張と埋め込み』の著者、PHP カーネルの専門家、PHP マスターは全員この本を読んだと思いますが、おそらく彼女が実際には女性であることをご存知ないでしょう<li> </li> </ul>Lars Bak や Mike Pall のような仮想マシンの分野のトップの専門家はいませんが、これらの専門家が協力して仮想マシンを作成できれば、大きな問題にはならないでしょう。では、彼らはどのような課題に直面するでしょうか?次に、それらについて 1 つずつ説明します。 <p> </p>仕様は何ですか? <h3> </h3>独自の PHP 仮想マシンを作成するときに直面する最初の問題は、PHP には言語仕様がなく、多くのバージョン間で構文に互換性がないことです (5.2.1 や 5.2.3 などの小さなバージョン番号であっても)。 PHPの言語仕様はどうなるのでしょうか? IEEE の声明を見てみましょう: <p> </p> <blockquote>PHP グループは、PHP (言語) の仕様について最終決定権を持っていると主張しています。このグループの仕様は実装であり、散文仕様や合意された検証スイートはありません。 <p> </p> したがって、唯一の方法は、Zend の実装を正直に検討することです。幸いなことに、これは HPHPc で一度実行されているため、HHVM はそれを直接使用できるため、この問題はそれほど大きくありません。 </blockquote> <p>言語または拡張子? </p> <h3 id="PHP-言語の実装は-仮想マシンの実装と同じくらい簡単ではありません-PHP-言語自体にもさまざまな拡張機能が含まれており-これらの拡張機能は-使用できるさまざまな機能を実装するために絶えず機能します-PHP-コードを分析すると-空白行のコメントを除いた-C-コードには-万行以上あることがわかります-そして-Zend-エンジンの部分がいくつあると思いますか-行数は-行弱です"> PHP 言語の実装は、仮想マシンの実装と同じくらい簡単ではありません。PHP 言語自体にもさまざまな拡張機能が含まれており、これらの拡張機能は、使用できるさまざまな機能を実装するために絶えず機能します。 PHP コードを分析すると、空白行のコメントを除いた C コードには 80 万行以上あることがわかります。そして、Zend エンジンの部分がいくつあると思いますか。行数は 100,000 行弱です。 </h3> <p>これは開発者にとっては悪いことではありませんが、エンジンの実装者にとっては非常に悲劇的です。これを Java 仮想マシンを作成するには、バイトコード解釈と Java で構築されたいくつかの基本的な JNI 呼び出しのみを実装する必要があります。 -in ライブラリは Java で実装されるため、パフォーマンスの最適化を考慮しない場合、ワークロードの観点からは、JVM よりも PHP 仮想マシンを実装する方がはるかに困難です。たとえば、8,000 行の TypeScript を使用して JVM を実装した人もいます。 。 </p> <p>この問題に対して、HHVM の解決策は非常にシンプルです。つまり、Facebook で使用されているものを実装するだけであり、HPHPc で以前に記述されたものを使用することもできるため、問題は大きくありません。 </p> <h3 id="インタプリタの実装">インタプリタの実装</h3> <p>次のステップはインタプリタの実装です。PHP を解析した後、HHVM によって設計されたバイトコードが生成され、再利用のために <code>~/.hhvm.hhbc (SQLite ファイル) に保存されます。バイトコードを実行するときは、Zend と同様であり、別のバイトコードも配置されます。 into さまざまな関数で実装されます (このメソッドには仮想マシン内で特別な名前が付いています: サブルーチン スレッド)

インタープリタの本体は bytecode.cpp に実装されています。 VMExecutionContext::iopAdd などのメソッドの場合、最終的な実行は tv-arith.cpp に実装されています。それの

<code class="c++"><div class="blockcode"> <div id="code_oM7"><ol> <li>if (c2.m_type == KindOfInt64) return o(c1.m_data.num, c2.m_data.num);</li> <li>if (c2.m_type == KindOfDouble) return o(c1.m_data.num, c2.m_data.dbl);</li> </ol></div> <em onclick="copycode($('code_oM7'));">复制代码</em> </div>

正是因为有了 Interpreter,HHVM 在对于 PHP 语法的支持上比 HPHPc 有明显改进,理论上做到完全兼容官方 PHP,但仅这么做在性能并不会比 Zend 好多少,由于无法确定变量类型,所以需要加上类似上面的条件判断语句,但这样的代码不利于现代 CPU 的执行优化,另一个问题是数据都是 boxed 的,每次读取都需要通过类似 m_data.numm_data.dbl

if (c2.m_type == KindOfInt64) return o(c1.m_data.num, c2.m_data.num);

if (c2.m_type == KindOfDouble) return o(c1.m_data.num, c2.m_data.dbl);

コードをコピー

    まさにその理由インタプリタの HHVM は、HPHPc に比べて PHP 構文のサポートが大幅に向上していますが、理論的には公式の PHP と完全に互換性があります。ただし、変数の型を決定できないため、これだけではパフォーマンスが大幅に向上します。上記と同様の条件ステートメントを追加する必要がありますが、そのようなコードは最新の CPU の実行の最適化に役立ちません。もう 1 つの問題は、データがボックス化されており、各読み取りが m_data.num のようなものを通過する必要があることです。 および m_data.dbl メソッドを使用して間接的に取得します。
  • このような問題の場合は、JIT に頼って最適化する必要があります。
  • JITと最適化を実装する
  • まず第一に、PHP の JIT はこれまで試されていないことを言及する価値があります。

2008 年に LLVM を実験した人もいますが、その結果は元のものより 21 倍遅かったです。 。 。

2010 年に、日本 IBM 研究所は、JVM 仮想マシン コードに基づいて P9 を開発しました。そのパフォーマンスは、公式の PHP の 2.5 ~ 9.5 倍です。「PHP 用に改良されたジャストインタイム コンパイラーの評価」を参照してください。 <div class="blockcode"> 2011 年に、Andrei Homescu は RPython に基づいて開発し、論文 HappyJIT: PHP 用のトレース JIT コンパイラーを書きましたが、テスト結果はまちまちで理想的ではありませんでした。 <div id="code_JSG"> <ol> <li>それでは、JIT とは一体何でしょうか? JIT を実装するにはどうすればよいですか? </li> <li> </li> <li>動的言語には、基本的に eval メソッドがあり、実行のために文字列を渡すことができます。JIT も同様のことを行いますが、文字列ではなく、異なるプラットフォーム上のマシンコードを結合して実行する必要がありますが、その方法は異なります。 Cで実装するには? Eli が書いたこの導入例を参照してください。記事のコードの一部を次に示します。 </li> <li> <li> <li> </ol> </div>unsigned char code[] = {<em onclick="copycode($('code_JSG'));"> 0x48, 0x89, 0xf8, // mov %rdi, %rax</em> 0x48, 0x83, 0xc0, 0x04, // add $4, %rax</div> 0xc3 // ret🎜} ;🎜memcpy(m, code, sizeof(code));🎜🎜🎜コードをコピー🎜🎜

ただし、マシンコードを手作業で記述する場合は間違いが起こりやすいため、Mozilla の Nanojit や LuaJIT の DynASM などの補助ライブラリを使用するのが最善ですが、HHVM ではこれらを使用せず、x64 のみをサポートするライブラリを実装します (さらに、VIXL を使用して ARM 64 ビットを生成し、mprotect を通じてコードを実行可能にしようとしています。

しかし、なぜ JIT コードのほうが速いのでしょうか?実際、C++ で書かれたコードは最終的にはマシン コードにコンパイルされますが、同じコードが手動でマシン コードに変換された場合、GCC によって生成されたものとの違いは何でしょうか。先ほど CPU の実装原理に基づいた最適化手法について説明しましたが、JIT におけるより重要な最適化は、タイプに基づいて特定の命令を生成することにより、命令と条件判断の数を大幅に削減することです。TraceMonkey の次の図は、これを示しています。非常に直感的な比較です。後で HHVM の具体的な例を見てみましょう:

HHVM 是如何提升 PHP 性能的?

HHVM は最初にインターピーターを通じて実行されますが、その後いつ JIT を使用するのでしょうか?一般的な JIT トリガー条件は 2 つあります:

  • trace: ループの実行回数が一定の回数を超えた場合、このコードを JIT します
  • メソッド: 関数の実行数を記録し、一定の数を超えた場合は、関数全体を JIT するか、関数を直接インライン化します

2 つの方法のどちらが優れているかについては、Lambada に関する投稿があり、さまざまな専門家、特に Mike Pall (LuaJIT 著者)、Andreas Gal (Mozilla VP)、Brendan Eich (Mozilla CTO) からの議論を集めています。私自身の意見もたくさんありますし、皆さんにも見ていただくことをお勧めしますので、ここではひけらかしません。

それらの違いはコンパイル範囲だけではなく、ローカル変数の処理など多くの詳細も異なりますが、ここでは説明しません

しかし、HHVM はこれら 2 つのメソッドを使用せず、タイプに応じて分割されたトレースレットと呼ばれる独自のメソッドを作成しました。

HHVM 是如何提升 PHP 性能的?関数を 3 つの部分に分割していることがわかります。上の 2 つの部分は、$k<p> が整数または文字列である 2 つの異なる状況を処理するために使用されているため、下の部分は戻り値であるようです。 Tracelet の解析と解体方法の詳細については、時間がありませんでしたので、Translator.cpp の <code>Translator::analyze<code>$k 为整数或字符串两种不同情况的,下面的部分是返回值,所以看起来它主要是根据类型的变化情况来划分 JIT 区域的,具体是如何分析和拆解 Tracelet 的细节可以查看 Translator.cpp 中的 Translator::analyze メソッドを参照してください。まだ見てくださいので、ここでは説明しません。

もちろん、高パフォーマンスの JIT を実現するには、さまざまな試みと最適化が必要です。たとえば、最初は、HHVM の新しく追加されたトレースレットが前に配置されます。つまり、上の図の A と C の位置が入れ替わります。後は後ろに入れてみた結果、事前に反応型を打ちやすいことがテストで判明したので14%向上しました

JIT の実行プロセスは、まず HHBC を SSA (hhbc-translator.cpp) に変換し、次に SSA を最適化 (コピー伝播など) し、それをローカル マシン コードに再生成します。たとえば、X64 では、トランスレーターによって実装されます。 -x64.cppの。

次の PHP 関数など、HHVM によって最終的に生成されるマシンコードがどのようなものかを確認するために、簡単な例を使用してみましょう。

<div class="blockcode"> <div id="code_B9S"> <ol> <li><?php<li>function a($b){<li> echo $b + 2;<li>}</ol></div><em onclick="copycode($('code_B9S'));">复制代码</em></div>

function a($b){ echo $b + 2;<div class="blockcode">} <div id="code_ZLy"><ol><em onclick="copycode($('code_B9S'));">コードをコピーします<li><li><li> <li>コンパイル後は次のようになります:<li> <li><li><li><li><li>mov rcx,0x7200000<li>mov rdi,rbp<li>mov rsi,rbx<li>mov rdx,0x20<li>call 0x2651dfb <HPHP::Transl::traceCallback(HPHP::ActHP::TypedValue*, *, long 、 void*)></li> <li>cmp BYTE PTR [rbp-0x8],0xa</li> <li>jne 0xae00306</li> <li>; 前のステップはパラメータが有効かどうかを確認することです</li> <li> <li>mov rcx,QWORD PTR [rbp-0x10]; ここでは %rcx が割り当てられています。値 1 </li> <li>mov edi,0x2 ; %edi (つまり、%rdi の下位 32 ビット) を 2 に割り当てます </li> <li>add rdi,rcx ; %rcx を追加します </li> <li>call 0x2131f1b <HPHP::print_int(long)> ; print_int 関数を呼び出します。この時点で、最初のパラメーター %rdi の値はすでに 3 です</li> <li> <li>; これについては後で説明しません</li> <li>mov BYTE PTR [rbp+0x28],0x8</li> <li>lea rbx,[rbp+0x20]</li> </ol>テストバイト PTR [r12]、0xffnjne 0xae0032A</div>プッシュ QWORD PTR [RBP+0x8] <em onclick="copycode($('code_ZLy'));">mov RBP、QWORD PTR [RBP+0x0] </em>mov RDI、RBP</div>mov RSI、RBX🎜mov RDX、QWORD PTR [RSP] 🎜 6b70e &E lt; hphp: :JIT::traceRet(HPHP::ActRec*, HPHP::TypedValue*, void*)>🎜ret 🎜🎜🎜コードをコピー🎜🎜

そして、HPHP::print_int 関数の実装は次のようになります:

<div class="blockcode"><div id="code_K6f"><ol> <code class="c++ c++" data-lang="c++"><div class="blockcode"> <div id="code_K6f"><ol> <li>void print_int(int64_t i) {</li> <li> char buf[256];</li> <li> snprintf(buf, 256, "%" PRId64, i);</li> <li> echo(buf);</li> <li> TRACE(1, "t-x64 output(int): %" PRId64 "n", i);</li> <li>}</li> </ol></div> <em onclick="copycode($('code_K6f'));">复制代码</em> </div>

可以看到 HHVM 编译出来的代码直接使用了 int64_tvoid print_int(int64_t i) {

char buf[256] ];

snprintf(buf, 256, "%" PRId64, i);

echo(buf);<div class="blockcode"> <div id="code_K70"><ol><li>-v Eval.JitWarmupRequests=0</li></ol></div> <em onclick="copycode($('code_K70'));">复制代码</em> </div> TRACE(1, "t-x64 Output(int): %" PRId64 "n", i);

}

コードをコピー

HHVM によってコンパイルされたコードは、インタープリターを回避して、int64_t

を直接使用していることがわかります。パラメータの判定と間接的なデータ取得の問題が解決され、最終的には C でコンパイルされたコードとほぼ同じになります。 <div class="blockcode"> <div id="code_biL"><ol> <li><?hh<li>class Point2 {<li> public float $x, $y;<li> function __construct(float $x, float $y) {<li> $this->x = $x;</li> <li> $this->y = $y;</li> <li> }</li> <li>}</li> <li>//来自:https://raw.github.com/strangeloop/StrangeLoop2013/master/slides/sessions/Adams-TakingPHPSeriously.pdf</li> </ol></div> <em onclick="copycode($('code_biL'));">复制代码</em> </div>

注意到 float

注: サーバー モードでは、HHVM は 12 を超えるリクエストがある場合にのみ JIT をトリガーします。HHVM を起動するときに、最初のリクエストで JIT を使用するように次のパラメーターを追加できます。 <div class="blockcode"><div id="code_K70"> <ol><p>-v Eval.JitWarmupRequests=0</p></ol> <em onclick="copycode($('code_K70'));">コードをコピー</em>します<h2></h2> <p>そのため、パフォーマンスをテストするときは、1 回か 2 回実行しただけでは効果が見られないことに注意する必要があります。 。 </p> <p>型導出は非常に面倒なので、プログラマにわかりやすく書かせるようにすべきです</p> <p> JIT の鍵は型を推測することです。そのため、特定の変数の型が時間の経過とともに変化すると、最適化が難しくなります。そのため、HHVM エンジニアは、PHP 構文に工夫を凝らし、型サポートを追加することを検討し始め、新しい型を立ち上げました。言語 - Hack (Tucao) この名前は SEO にはあまり良くありません)、次のようになります: </p> <code class="php php" data-lang="php"><div class="blockcode"><div id="code_biL"> <ol></ol> <ul><?hh<li>class Point2 {</li> public float $ x, $y;<li> function __construct(float $x, float $y) {</li> $this->x = $x;<li> $this->y = $y;</li> }</ul>}<p>//From: https ://raw.github.com/strangeloop/StrangeLoop2013/master/slides/sessions/Adams-TakingPHPSeriously.pdf</p> <em onclick="copycode($('code_biL'));">コードをコピー em><p></p> <h2> <code>float キーワードに気づきましたか?静的型を使用すると、HHVM のパフォーマンスをより最適化できますが、PHP 構文と互換性がなく、HHVM のみを使用できることも意味します。
  • 実際、これを行うことの最大の利点は、Dart のオプション型と同様に、コードを理解しやすくし、意図しないミスを減らすことだと思います。これは、IDE の識別も容易になります。 Facebook はコードを共同編集できる Web ベースの IDE を開発中であるため、期待できると述べています。
  • HHVMは使用できますか?
  • 一般的に、以前の HPHPc と比較して、HHVM は実際の仮想マシンであり、さまざまな PHP 構文をより適切にサポートできるため、変更コストが高くならず、シームレスに切り替えることができるため、試してみる価値があると思います。公式 PHP バージョンを使用すると、FPM を同時に起動して、いつでも通話できるようになります。HHVM には、緊急時の準備ができている限り、リスクは制御可能であり、いつでも通話できるようになります。ロングラン。
  • 実際のテストには独自のビジネス コードを使用する必要があります。これを取得することでのみ、HHVM がどの程度のメリットをもたらすか、特に全体的なパフォーマンスがどの程度向上するかを知ることができます。データを基に意思決定を行うことができます。
  • 最後に、使用する予定がある方は、次のことを参照してください。
  • 拡張機能の問題: PHP 拡張機能を使用する場合は、書き直す必要があります。ただし、HHVM 拡張機能は、Zend よりもはるかに簡単に作成できます。詳細については、Wiki の例を参照してください。
  • HHVM サーバーの安定性の問題: このマルチスレッド アーキテクチャは、一定期間実行するとメモリ リークを引き起こす可能性があり、PHP の作成が不十分であるとプロセス全体のハングアップを直接引き起こす可能性があるため、テストと災害復旧に注意を払う必要があります。この分野の対策を講じます。
  • 問題修復の難しさ: 問題が発生した場合、HHVM は Zend よりも修復が難しく、特に JIT コードがより安定することを祈るばかりです。
  • 追記:実際、私は基本的な仮想マシンの知識しかなく、この記事を書く際に一時的に情報を探したことが多く、必然的に不正確な部分が含まれます。コメントやアドバイスを歓迎します:)
  • 2014 年 1 月追加: 工場における HHVM の現在のプロモーションの勢いは非常に良好で、特に互換性テストが 98.58% に達し、修正コストがさらに削減されたため、2014 年にすべての人に試してもらうことをお勧めします。
AMAのアンドレイ・アレクサンドルスク
キース・アダムスのHNに関する手がかり
3 人の男がどのように Facebook の基盤を再構築したか

HHVM を使用したメタル上の PHP🎜 🎜HPHPi を高速化する🎜 🎜HHVM 最適化のヒント🎜 🎜JIT の速度での HipHop 仮想マシン (hhvm) PHP 実行🎜 🎜Julien Verlaguet、Facebook: PHP の静的分析🎜 🎜HHVM による PHP ベースの開発の高速化🎜 🎜HHBC へのオペコードの追加🎜 🎜🎜🎜🎜 🎜 🎜 🎜 🎜🎜 🎜🎜
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

セッションのハイジャックはどのように機能し、どのようにPHPでそれを軽減できますか? セッションのハイジャックはどのように機能し、どのようにPHPでそれを軽減できますか? Apr 06, 2025 am 12:02 AM

セッションハイジャックは、次の手順で達成できます。1。セッションIDを取得します。2。セッションIDを使用します。3。セッションをアクティブに保ちます。 PHPでのセッションハイジャックを防ぐための方法には次のものが含まれます。1。セッション_regenerate_id()関数を使用して、セッションIDを再生します。2。データベースを介してストアセッションデータを3。

確固たる原則と、それらがPHP開発にどのように適用されるかを説明してください。 確固たる原則と、それらがPHP開発にどのように適用されるかを説明してください。 Apr 03, 2025 am 12:04 AM

PHP開発における固体原理の適用には、次のものが含まれます。1。単一責任原則(SRP):各クラスは1つの機能のみを担当します。 2。オープンおよびクローズ原理(OCP):変更は、変更ではなく拡張によって達成されます。 3。Lischの代替原則(LSP):サブクラスは、プログラムの精度に影響を与えることなく、基本クラスを置き換えることができます。 4。インターフェイス分離原理(ISP):依存関係や未使用の方法を避けるために、細粒インターフェイスを使用します。 5。依存関係の反転原理(DIP):高レベルのモジュールと低レベルのモジュールは抽象化に依存し、依存関係噴射を通じて実装されます。

システムの再起動後にUnixSocketの権限を自動的に設定する方法は? システムの再起動後にUnixSocketの権限を自動的に設定する方法は? Mar 31, 2025 pm 11:54 PM

システムが再起動した後、UnixSocketの権限を自動的に設定する方法。システムが再起動するたびに、UnixSocketの許可を変更するために次のコマンドを実行する必要があります:sudo ...

phpstormでCLIモードをデバッグする方法は? phpstormでCLIモードをデバッグする方法は? Apr 01, 2025 pm 02:57 PM

phpstormでCLIモードをデバッグする方法は? PHPStormで開発するときは、PHPをコマンドラインインターフェイス(CLI)モードでデバッグする必要がある場合があります。

PHPでの後期静的結合を説明します(静的::)。 PHPでの後期静的結合を説明します(静的::)。 Apr 03, 2025 am 12:04 AM

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPのCurlライブラリを使用してJSONデータを含むPOSTリクエストを送信する方法は? PHPのCurlライブラリを使用してJSONデータを含むPOSTリクエストを送信する方法は? Apr 01, 2025 pm 03:12 PM

PHP開発でPHPのCurlライブラリを使用してJSONデータを送信すると、外部APIと対話する必要があることがよくあります。一般的な方法の1つは、Curlライブラリを使用して投稿を送信することです。

See all articles