47

インタープリター言語の長所と短所について読んでいましたが、最も一般的な短所の 1 つは遅いことですが、インタープリター言語のプログラムはなぜ遅いのでしょうか?

4

15 に答える 15

78

ネイティブ プログラムは、実行するプロセッサ用に記述された命令を使用して実行されます。

解釈された言語は、まさに「解釈された」言語です。他の形式の命令は、ランタイムによって読み取られて解釈され、次にネイティブのマシン命令が実行されます。

このように考えてください。母国語で誰かと話すことができれば、通訳者があなたの言語を他の言語に翻訳して聞き手が理解できるようにするよりも、一般的には迅速に機能します。

上記の説明は、言語がインタープリターで実行されている場合のものであることに注意してください。多くの言語用のインタープリターがあり、ネイティブ マシン命令をビルドするためのネイティブ リンカーもあります。速度の低下 (ただし、そのサイズは異なる場合があります) は、解釈されたコンテキストにのみ適用されます。

したがって、言語が遅いと言うのは少し間違っています。むしろ、遅いのは言語が実行されているコンテキストです。

C# はインタープリター型言語ではありません。中間言語 (IL) を使用していますが、これは実行前にネイティブ命令に JIT されているため、すべてではありませんが、同じように速度が低下します。 C# または C++ 用の本格的なインタープリターを作成した場合、実行速度も遅くなります。

明確にするために、「遅い」と言うとき、それはもちろん相対的な用語です。

于 2009-11-07T21:05:17.280 に答える
35

すべての答えは、ここで本当に重要な点を見逃しているようです。「解釈された」コードがどのように実装されるかの詳細です。

メソッド、オブジェクト、およびグローバル変数空間モデルが動的であるため、解釈されたスクリプト言語は遅くなります。私の意見では、これはスクリプト言語の実際の定義であり、解釈されるという事実ではありません。これには、変数またはメソッド呼び出しへのアクセスごとに、多くの追加のハッシュ テーブル ルックアップが必要になります。そして、それがマルチスレッドと GIL (Global Interpreter Lock) の使用がひどい主な理由です。このルックアップは、ほとんどの時間が費やされる場所です。これは苦痛なランダム メモリ ルックアップであり、L1/L2 キャッシュ ミスが発生すると非常に苦痛になります。

Google の Javascript Core8 は非常に高速で、単純な最適化のためにほぼ C の速度をターゲットにしています。オブジェクト データ モデルを固定として取り、ネイティブ コンパイル プログラムのデータ構造のようにアクセスするための内部コードを作成します。新しい変数またはメソッドが追加または削除されると、コンパイルされたコード全体が破棄され、再度コンパイルされます。

この手法は、Deutsch/Schiffman の論文「Efficient Implementation of the Smalltalk-80 System」で詳しく説明されています。

なぜ php、python、ruby がこれを行わないのかという質問への回答は非常に簡単です。この手法の実装は非常に複雑です。

そして、JavaScript に支払うお金を持っているのは Google だけです。高速なブラウザベースの JavaScript インタープリターは、数十億ドル規模のビジネス モデルの基本的なニーズだからです。

于 2009-12-02T02:03:20.837 に答える
10

インターピーターは、たまたま持っていないマシンのエミュレーターと考えてください。

簡単に言えば、コンパイルされた言語はマシン命令によって実行されるのに対し、解釈された言語はソースまたはバイトコードのいずれかを読み取り、プログラムを実行した仮想マシンを本質的にエミュレートするプログラム (コンパイルされた言語で記述された) によって実行されるということです。マシンが存在する場合は直接。

解釈されたランタイムは、現時点では実際には持っていないマシンのエミュレーターと考えてください。

これは明らかに、Java や C# などの JIT (ジャスト イン タイム) コンパイラによって複雑になります。理論的には、これらの言語は「AOT」(「At One Time」) コンパイラと同じくらい優れていますが、実際には、これらの言語は実行速度が遅く、プログラムの実行時にメモリと時間を消費するコンパイラが必要になるというハンディキャップがあります。しかし、ここでそのようなことを言う場合は、JIT と AOT の間に理論的な違いはないと主張する熱狂的な JIT 擁護者を引き付ける準備をしてください。Java や C# は C や C++ と同じくらい速いかと尋ねると、彼らは言い訳をし始め、少し落ち着いてきます。:-)

そのため、利用可能なコンピューティングの最大量を常に使用できるゲームでは、C++ が完全に支配します。

デスクトップや Web では、コンピューターが非常に高速で、問題が計算集約的ではないため、情報指向のタスクは、より抽象化されているか、少なくともコンパイルが少ない言語によって行われることがよくあります。 -市場、プログラマーの生産性、信頼性の高いメモリセーフ環境、動的なモジュール性、およびその他の強力なツール。

于 2009-11-08T00:28:44.913 に答える
7

これは良い質問ですが、私の意見では、「解釈された言語はコンパイルされた言語より遅いのはなぜですか?」のように、少し違った形で定式化する必要があります。

インタープリター言語自体が遅いというのはよくある誤解だと思います。解釈された言語は遅くはありませんが、ユースケースによっては、コンパイルされたバージョンよりも遅くなる場合があります。ほとんどの場合、インタープリター言語は実際には十分に高速です。

「十分に速い」ことに加えて、Python のような言語を使用することで生産性が向上します。たとえば、C は、インタープリター型言語を検討するのに十分な理由です。また、本当に速度が必要な場合は、解釈されたプログラムの特定の部分を高速な C 実装にいつでも置き換えることができます。ただし、最初に測定し、速度が本当に問題であるかどうかを判断してから、最適化してください。

于 2009-11-07T21:35:00.863 に答える
5

他の答えに加えて、最適化があります。プログラムをコンパイルするとき、通常、コンパイルにかかる時間は気にしません。コンパイラーはコードを最適化するのに多くの時間を費やします。コードを解釈するときは、非常に迅速に実行する必要があるため、より巧妙な最適化を行うことができない場合があります。

于 2009-11-07T21:08:15.057 に答える
4

100 回ループすると、ループの内容が 100 回低レベル コードに解釈されます。

キャッシュも再利用も最適化もされていません。

簡単に言えば、コンパイラは低レベルのコードに一度解釈します

編集、コメントの後:

  • JIT はコンパイルされたコードであり、解釈されません。事前にコンパイルするのではなく、後でコンパイルするだけです
  • 現代の実用的な実装ではなく、古典的な定義を参照します
于 2009-11-07T21:05:31.697 に答える
2

本当の簡単な答えのない簡単な質問。肝心なのは、すべてのコンピューターが実際に「理解している」のはバイナリ命令であり、これは C のような「高速な」言語がコンパイルされるものです。

次に、さまざまなバイナリ命令 (Java や .NET など) を理解する仮想マシンがありますが、これらは Just-In-Compiler (JIT) によってその場でマシン命令に変換する必要があります。これはほぼ同じ速度です (コードがどのように使用されているかについて、JIT は静的コンパイラよりも多くの情報を持っているため、特定のケースではさらに高速です)。

次に、通常は独自の中間バイナリ命令も持つインタープリター言語がありますが、インタープリターは、すべての命令のケースとその実行方法を含む大きな switch ステートメントを含むループのように機能します。基礎となるマシン コードに対するこのレベルの抽象化は低速です。より多くの命令が関与し、インタプリタで単純なことを行うための関数呼び出しの長いチェーンがあり、その結果、メモリとキャッシュが効果的に使用されていないと主張することができます。

しかし、インタープリター言語は、多くの場合、使用目的に対して十分に高速です。Web アプリケーションは常に、どのインタープリターよりも桁違いに遅い IO (通常はデータベース アクセス) に拘束されます。

于 2009-11-07T21:15:06.137 に答える
1

ええ、通訳言語は遅いです...

ただし、次の点を考慮してください。解決すべき問題がありました。Pythonで問題を解決するのに4分かかり、プログラムの実行には0.15秒かかりました。次に、Cで書き込もうとしましたが、実行時間は0.12秒で、書き込みに1時間かかりました。問題の問題を解決する実際的な方法はハッシュテーブルを使用することであり、とにかくハッシュテーブルがランタイムを支配していたためです。

于 2009-11-07T22:29:29.787 に答える
1

about.comから:

解釈された言語は実行時に処理されます。すべての行が読み取られ、分析され、実行されます。ループのたびに行を再処理しなければならないことが、インタープリター型言語を非常に遅くしている原因です。このオーバーヘッドは、解釈されたコードがコンパイルされたコードよりも 5 倍から 10 倍遅く実行されることを意味します。Basic や JavaScript などのインタープリター言語は、最も低速です。それらの利点は、変更後に再コンパイルする必要がないことであり、プログラミングを学ぶときに便利です。

ただし、Java や C# などの言語では、5 倍から 10 倍遅いということは必ずしも当てはまりません。それらは解釈されますが、ジャストインタイム コンパイラは一部の操作に対して機械語命令を生成できるため、劇的に高速化されます (コンパイルされた言語の速度に近い場合もあります)。

于 2009-11-07T21:05:37.327 に答える
1

インタープリター言語のようなものはありません。どの言語も、インタープリターまたはコンパイラーによって実装できます。最近では、ほとんどの言語でコンパイラを使用した実装が行われています。

とはいえ、インタープリターは実行時に言語またはそれに近いものを処理し、それを機械命令に変換する必要があるため、通常は低速です。コンパイラはこの機械語命令への変換を 1 回だけ行い、その後直接実行します。

于 2009-11-07T21:11:02.917 に答える
0

解釈された言語は、実行時にソース コードを読み取って解釈する必要があります。コンパイルされたコードでは、その解釈の多くが事前に (コンパイル時に) 行われます。

于 2009-11-07T21:06:35.343 に答える
0

最近では、「解釈」されている現代のスクリプト言語ほとんどありません。それらは通常、マシンコードまたは仮想マシンで (より効率的に) 実行される何らかの中間バイトコード言語にその場でコンパイルされます。

そうは言っても、CPUが「コードの行」ごとにより多くの命令を実行しているため、速度が遅くなります。命令の多くは、行のセマンティクスが示唆することを行うのではなく、コードの理解に費やされるためです!

于 2009-11-07T21:07:21.707 に答える
0

解釈された言語の長所と短所を読む

これは、問題の投稿に関連するアイデアです。

インタプリタによる実行は通常、通常のプログラム実行よりもはるかに効率的ではありません。これは、すべての命令が実行時に解釈を渡す必要があるか、新しい実装のように、コードを実行する前に中間表現にコンパイルする必要があるために発生します。

于 2009-11-07T21:09:04.280 に答える
0

母国語よりも翻訳機を介して話す方が遅いのと同じ理由で. または、辞書を引いて読む。翻訳に時間がかかります。

更新:いいえ、私の答えが受け入れられたものとある程度同じであることはわかりませんでした;-)

于 2009-11-07T21:10:07.737 に答える