38

私の見解では、PHP と Java はどちらも似たような構造を持っています。最初に高レベルのコードをいくつか書きます。それを VM で実行できるように、より単純なコード形式に変換する必要があります。1 つの違いは、PHP はソース コード ファイルから直接動作するのに対し、Java はバイトコードを .class ファイルに格納し、そこから VM がそれらをロードできることです。

今日では、高速な PHP 実行の要件が高まっているため、ユーザーがファイルにアクセスするたびにコンパイル手順を実行するのではなく、オペコードを直接操作する方がよいと人々は信じています。

解決策は、基本的にコンパイルされた結果をキャッシュに保存し、再度コンパイルする代わりにキャッシュされたオペコードを使用する、いわゆる Accelerators の負荷のようです。

Facebook が行った別のアプローチは、PHPコードを別の言語に完全にコンパイルすることです。

私の質問は、PHP の世界で Java と同じことをする人がいないのはなぜですか? 毎回再コンパイルする必要がある動的要素などはありますか? それ以外の場合は、コードが本番環境に入ったときにすべてをコンパイルしてから、それで作業する方が賢明です。

4

5 に答える 5

52

最も重要な違いは、JVM にはバイトコードを完全にカバーする明示的な仕様があることです。これにより、バイトコード ファイルは移植可能になり、特定の JVM 実装による実行だけでなく、有用になります。

PHP には言語仕様すらありません。PHP オペコードは、特定の PHP エンジンの実装の詳細であるため、それらを使って興味深いことを実際に行うことはできません。

于 2012-05-23T09:17:35.543 に答える
12

PHPのオペコードはJavaのクラスファイルと同じではありません。Javaクラスファイルは適切に指定されており、マシン間で移植可能です。PHPオペコードは移植性がありません。たとえば、メモリアドレスが組み込まれています。これらは厳密にはPHPインタープリターの実装の詳細であり、Javaバイトコードのようなものと見なすべきではありません。

このようにする必要がありますか?いいえ、おそらくそうではありません。しかし、PHPのソースコードはめちゃくちゃであり、これを実現したいという願望も、PHP内部コミュニティの政治的意志もありません。オペコードキャッシュをPHP6に焼き付けるという話があったと思いますが、PHP 6が死んでしまい、そのアイデアの状況はわかりません。

参考:私はphcを書いたので、数年間PHPの実装/コンパイルにかなり深く関わっていました。

于 2012-05-29T20:39:27.270 に答える
3

皆さん誤解されていると思います。HHVM は別の言語へのコンパイラではなく、仮想マシンそのものです。混乱は、Facebook が C++ にコンパイルするために使用するためですが、そのアプローチは、開発者の要件に対してゆっくりとしたものでした (いくつかの小さなことをテストするためだけに 10 分間コンパイルします)。

于 2013-12-29T15:44:08.090 に答える
3

PHP はオペコードの標準メカニズムを使用しません。スタック VM (python、java) またはレジスタ VM (x86、perl6 など) に固執することを望みます。しかし、それは完全に自家製のものを使用しており、そこには摩擦があります。

これは、各オペコードが ->op1 ->op2 および ->result を持つメモリ内の接続されたリストを使用します。現在、これらのそれぞれは、一時テーブルなどの定数またはエントリのいずれかです。これらのポインターは、適切な方法でシリアル化することはできません。

現在、ストリームをディスクにダンプする pecl/bcompiler などのアイテムを使用してこれを達成しています。

しかし、クラスはこれをさらに複雑にします。つまり、次のような潜在的なコード フラグメントがあることを意味します。

if(<conditon>)
{
   class XYZ() { }
}
else 
{
   class XYZ() { }
}

class ABC extends XYZ {}

これは、クラスと関数に関する多数の決定が実行時にのみ行われることを意味します。Java のようなものは、実行時に条件付きで定義される同じ名前の 2 つのクラスで窒息します。基本的に、APC の継承とクラス キャッシング コードは、おそらくコードベースの中で最も複雑でバグが発生しやすい部分です。クラスがキャッシュされるときはいつでも、すべての親の継承されたメンバーは、オペコード キャッシュに保存する前にスクラブ アウトする必要があります。

ポインターの問題は克服できないわけではありません。再起動が行われるたびにキャッシュエントリ全体をディスクから直接ロードするためにわざわざ修正したことのない apc_bindump があります。しかし、すべてのシステム ポインターを特定する必要があるものを取得するためにすべてをデバッグするのは面倒です。フォークの動作により、すべての php プロセスが同じシステム ポインターを持っているため、apache の場合は簡単すぎます。古いバージョンの fastcgi は、最初に fork し、後で php を初期化していたため、処理が遅くなりました。

しかし最終的に、PHP に本当に欠けているのは、バイトコード形式を発明し、現在のエンジンとすべてのモジュールを捨て、スタック VM を使用してそれを書き直し、JIT を構築するという意志です。時間があればいいのにと思います。fb の連中は、ヒップホップ HHVM を持ってほとんどそこにいます。これは、より高速なパフォーマンスのために eval() を犠牲にします-これは公正な犠牲です:)

PS: 私は、APC を 5.4 に適切に更新する時間を見つけられない男です。

于 2012-06-01T16:14:44.350 に答える