230

Java では「仮想マシン」が常に使用されていますが、Python の「仮想マシン」を読むことはめったにないようです。

どちらもバイトコードを解釈します。1 つを仮想マシンと呼び、もう 1 つをインタープリターと呼ぶのはなぜですか?

4

14 に答える 14

180

この投稿では、「仮想マシン」は、Qemu や Virtualbox などのシステム仮想マシンではなく、プロセス仮想マシンを指します。プロセス仮想マシンは、単純に、一般的なプログラミング環境を提供するプログラム、つまりプログラミング可能なプログラムです。

Java にはインタープリターと仮想マシンがあり、Python には仮想マシンとインタープリターがあります。「仮想マシン」が Java でより一般的な用語であり、「インタープリター」が Python でより一般的な用語である理由は、静的型付け (Java) と動的型付け (Python) という 2 つの言語の主な違いに大きく関係しています。このコンテキストでは、「型」は プリミティブ データ型を指します。つまり、データのメモリ内ストレージ サイズを示す型です。Java 仮想マシンは簡単です。プログラマは、各変数のプリミティブ データ型を指定する必要があります。これは、Java バイトコードが Java 仮想マシンによって解釈および実行されるだけでなく、マシン命令にコンパイルされるのに十分な情報を提供します。. Python 仮想マシンは、各操作の実行前に一時停止して、操作に含まれる各変数またはデータ構造のプリミティブ データ型を決定するという追加のタスクを実行するという意味で、より複雑です。Python は、プリミティブ データ型の観点からプログラマーを解放し、操作をより高いレベルで表現できるようにします。この自由の代償はパフォーマンスです。「インタープリター」は、データ型を検査するために一時停止する必要があるため、また動的型付け言語の比較的簡潔な構文が対話型インターフェイスに適しているため、Python の優先用語です。インタラクティブな Java インターフェイスを構築するのに技術的な障壁はありませんが、静的に型付けされたコードをインタラクティブに記述しようとするのは面倒なので、そのようには行われません。

Java の世界では、実際にマシン命令にコンパイルできる言語で記述されたプログラムを実行する仮想マシンが注目を集めており、その結果、速度とリソース効率が向上します。Java バイトコードは、比較的言えば、コンパイルされたプログラムのパフォーマンスに近いパフォーマンスで Java 仮想マシンによって実行できます。これは、バイトコードにプリミティブ データ型情報が存在するためです。Java 仮想マシンは、Java を独自のカテゴリに分類します。

移植可能な解釈された静的に型付けされた言語

次に近いのは LLVM ですが、LLVM は異なるレベルで動作します。

移植可能な解釈されたアセンブリ言語

「バイトコード」という用語は Java と Python の両方で使用されますが、すべてのバイトコードが同じように作成されるわけではありません。バイトコードは、コンパイラ/インタープリターによって使用される中間言語の総称です。gcc のような C コンパイラでさえ、中間言語 (または複数)を使用して作業を完了します。Java バイトコードにはプリミティブ データ型に関する情報が含まれていますが、Python バイトコードには含まれていません。この点で、Python (および Bash、Perl、Ruby など) の仮想マシンは、Java 仮想マシンよりも根本的に遅いというか、単純にやるべきことが多いということです。さまざまなバイトコード形式に含まれる情報を検討すると便利です。

  • llvm: CPU レジスタ
  • Java:プリミティブ データ型
  • Python:ユーザー定義型

実世界で例えると、LLVM は原子を操作し、Java 仮想マシンは分子を操作し、Python 仮想マシンは材料を操作します。すべてが最終的に亜原子粒子に分解される必要があるため (実際のマシン操作)、Python 仮想マシンには最も複雑なタスクがあります。

静的型付け言語のインタープリター/コンパイラーは、動的型付け言語のインタープリター/コンパイラーと同じ荷物を持っていません。静的に型付けされた言語のプログラマーは、たるみを取る必要があり、その見返りはパフォーマンスです。ただし、すべての非決定論的関数が秘密裏に決定論的であるように、すべての動的型付け言語も秘密裏に静的型付けされています。したがって、2 つの言語ファミリ間のパフォーマンスの違いは、Python がその名前を HAL 9000 に変更する頃には平準化するはずです。

Python のような動的言語の仮想マシンは、理想化された論理マシンを実装しており、必ずしも実際の物理ハードウェアと密接に対応しているわけではありません。対照的に、Java 仮想マシンの機能は従来の C コンパイラに似ていますが、マシン命令を発行する代わりに組み込みルーチンを実行する点が異なります。Python では、整数は一連の属性とメソッドが関連付けられた Python オブジェクトです。Java では、int は指定されたビット数で、通常は 32 です。これは実際には公正な比較ではありません。Python の整数は、実際には Java の Integer クラスと比較する必要があります。Java の "int" プリミティブ データ型は、Python 言語のどのデータ型とも比較できません。Python 言語にはこのプリミティブのレイヤーがなく、Python バイトコードにも欠けているからです。

Java 変数は明示的に型付けされているため、JythonのパフォーマンスのようなものはcPythonと同じ球場にあると 合理的に期待できます。一方、Python で実装された Java 仮想マシンは、泥より遅いことがほぼ保証されています。また、Ruby や Perl などがうまくいくとは思わないでください。それらはそのように設計されていません。それらは、動的言語でのプログラミングと呼ばれる「スクリプト」用に設計されました。

仮想マシンで行われるすべての操作は、最終的に実際のハードウェアに影響を与える必要があります。仮想マシンには、論理操作の任意の組み合わせを実行するのに十分な汎用性を備えた、コンパイル済みのルーチンが含まれています。仮想マシンは新しいマシン命令を発行していない可能性がありますが、独自のルーチンを任意の複雑なシーケンスで何度も実行していることは確かです。Java 仮想マシン、Python 仮想マシン、およびそこにある他のすべての汎用仮想マシンは、想像できる任意のロジックを実行するように誘導できるという意味では同じですが、どのようなタスクを実行するかという点で異なります。引き受け、プログラマーに任せるタスク。

Psyco for Python は完全な Python 仮想マシンではありませんが、数行のコードをコンパイルできると思われるポイントで通常の Python 仮想マシンをハイジャックするジャストインタイム コンパイラです。 variable は、反復ごとに値が変化しても一定のままです。その場合、通常の仮想マシンの絶え間ないタイプの判別の一部を差し控えることができます。ただし、サイコの足元からタイプを引き抜かないように、少し注意する必要があります. ただし、Pysco は通常、タイプが変更されないという完全な確信がない場合は、通常の仮想マシンにフォールバックすることを知っています。

この話の教訓は、プリミティブ データ型情報がコンパイラ/仮想マシンにとって非常に役立つということです。

最後に、全体像を把握するために、次のことを考慮してください: iPhone で実行されている qemu 仮想マシンで実行されている LLVM で実行されている Java インタープリター/仮想マシンで実行されている Java で実行されている Python インタープリター/仮想マシンによって実行される Python プログラム。

パーマリンク

于 2009-11-13T22:47:18.057 に答える
145

仮想マシンは、特定の言語とは無関係にサポートされるアトミックで明確に定義された命令の特定のセットを備えた仮想コンピューティング環境であり、一般にそれ自体がサンドボックスと見なされます。VM は、特定の CPU の命令セットに類似しており、次の命令 (またはバイト コード) の非常に基本的なビルディング ブロックを使用して、より基本的なレベルで動作する傾向があります。命令は、仮想マシンの現在の状態のみに基づいて確定的に実行され、その時点での命令ストリーム内の他の場所の情報には依存しません。

一方、インタープリターは、周囲のトークンのコンテキストでデコードする必要がある特定の言語および特定の文法の構文のストリームを解析するように調整されているという点で、より洗練されています。各バイトや各行を個別に見て、次に何をすべきかを正確に知ることはできません。言語のトークンは、VM の命令 (バイト コード) に関連するように、分離して取得することはできません。

Java コンパイラは、C コンパイラが C 言語プログラムをアセンブリ コードに変換するのと同じように、Java 言語をバイト コード ストリームに変換します。一方、インタープリターは、プログラムを適切に定義された中間形式に実際に変換するのではなく、ソースを解釈するプロセスの問題としてプログラムのアクションを実行するだけです。

VM とインタープリターの違いのもう 1 つのテストは、VM が言語に依存しないと考えるかどうかです。Java VM として知られているものは、実際には Java 固有のものではありません。JVMで実行できるバイトコードを生成する他の言語からコンパイラを作成できます。一方で、Python インタープリターによる解釈のために、Python 以外の言語を Python に「コンパイル」することを本当に考えているとは思いません。

解釈プロセスが高度であるため、これは比較的遅いプロセスになる可能性があります。具体的には、言語トークンなどを解析して識別し、ソースのコンテキストを理解して、インタープリター内で実行プロセスを実行できるようにします。このようなインタープリター型言語を高速化するために、ここで、より容易に直接解釈できる、事前に解析され、事前にトークン化されたソース コードの中間形式を定義できます。この種のバイナリ形式は、実行時に解釈されます。パフォーマンスを向上させるために、人間が判読しにくい形式から開始するだけです。ただし、そのフォームを実行するロジックは仮想マシンではありません。これらのコードを分離して取得することはまだできないためです。周囲のトークンのコンテキストは依然として重要であり、よりコンピューター効率の高い別のフォームになっています。

于 2009-01-14T05:06:47.097 に答える
67

おそらく、用語が異なる理由の 1 つは、人間が読める生のソース コードを Python インタープリターに供給し、バイトコードなどを気にしないことを通常考えているためです。

Java では、明示的にバイトコードにコンパイルしてから、VM 上でソース コードではなく、バイトコードのみを実行する必要があります。

Python は内部で仮想マシンを使用していますが、ユーザーの観点からは、ほとんどの場合、この詳細を無視できます。

于 2009-01-14T03:56:21.230 に答える
19

Interpreterは、ソース コードを効率的な中間表現 (コード) に変換し、すぐにこれを実行します。

Virtual Machineは、インタープリター システムの一部であるコンパイラーによってビルドされた、保存済みのプリコンパイル済みコードを明示的に実行します。

仮想マシンの非常に重要な特性は、内部で実行されているソフトウェアが仮想マシンによって提供されるリソースに制限されていることです。正確には、仮想世界から抜け出すことはできません。リモート コードの安全な実行、Java アプレットを考えてみてください。

Python の場合、この投稿のコメントで述べたように、 pycファイルを保持している場合、メカニズムは VM に似たものになり、このバイトコードはより高速に実行されます。これは依然として解釈されますが、よりコンピューターに適した形式になります。 . これを全体として見ると、PVM は Python インタープリターの最後のステップです。

要するに、Python インタープリターを参照するときは、それを全体として参照していることを意味し、PVM と言うときは、ランタイム環境である Python インタープリターの一部について話しているだけであることを意味します。Java と同様に、JRE、JVM、JDK などのさまざまな部分を区別して参照します。

詳細については、ウィキペディアのエントリ:インタープリター、および仮想マシンを参照してください。ここにもう1つ。ここでは、アプリケーション仮想マシンの比較を見つけることができます。コンパイラ、インタープリタ、VM の違いを理解するのに役立ちます。

于 2009-01-14T07:44:54.187 に答える
12

インタープリターという用語は、以前のシェル スクリプト言語にさかのぼる古い用語です。「スクリプト言語」がフル機能の言語に進化し、対応するプラットフォームがより洗練されてサンドボックス化されているため、仮想マシンとインタープリター (Python の意味で) の違いは非常に小さいか、存在しません。

Python インタープリターは、別のコンパイル手順なしで実行できるという意味で、シェル スクリプトと同じように機能します。さらに、Python のインタープリター (または Perl や Ruby のインタープリター) と Java の仮想マシンの違いは、ほとんどが実装の詳細です。(Java は Python よりも完全にサンドボックス化されていると主張する人もいるかもしれませんが、どちらも最終的にはネイティブ C インターフェースを介して基礎となるアーキテクチャーへのアクセスを提供します。)

于 2009-01-14T04:27:47.767 に答える
11

それらの間に実際の違いはありません。人々は作成者が選択した慣習に従うだけです.

于 2009-01-14T03:41:23.023 に答える
3

Python には x86 用の JIT コンパイラがあり、問題がさらに混乱することを忘れないでください。(サイコを参照)。

「解釈された言語」のより厳密な解釈は、VM のパフォーマンスの問題を議論する場合にのみ役立ちます。言葉、文脈がすべてです。

于 2009-01-14T04:36:21.493 に答える
0

まず第一に、プログラミングやコンピューター サイエンスは一般的に数学ではなく、頻繁に使用する用語のほとんどについて厳密な定義がないことを理解する必要があります。

今あなたの質問に:

インタープリターとは(コンピューター サイエンスで)

ソースコードを実行可能な最小単位で変換し、その単位を実行します。

仮想マシンとは

JVM の場合、仮想マシンは、インタープリター、クラス ローダー、ガベージ コレクター、スレッド スケジューラー、JIT コンパイラー、その他多くのものを含むソフトウェアです。

ご覧のとおり、インタープリターは JVM の一部であり、JVM 全体をインタープリターと呼ぶことはできません。これには他の多くのコンポーネントが含まれているためです。

Pythonについて話すときに「インタープリター」という言葉を使用する理由

Java では、コンパイル部分が明示的です。一方、Python はコンパイルと解釈のプロセスについて Java のように明示的ではありません。エンド ユーザーの観点から見ると、解釈は Python プログラムを実行するために使用される唯一のメカニズムです。

于 2016-10-01T09:06:40.623 に答える