Compiler、JITコンパイラ、その都度のコンパイラ)とは、ソフトウェアの実行時にコードのコンパイルを行い実行速度の向上を図るコンパイラのこと。(Ahead-Of-Timeコンパイラ、AOTコンパイラ)と呼ぶ。Time」の名前が付けられた。動的コンパイルという用語は、実行時に機械語を生成するというより広い意味で使われることがあり、その意味ではJITコンパイルは動的コンパイルの一種と考えることができる。事前コンパイル方式と比べ、JIT方式ではコンパイル時間の分がプログラム実行時間に関するオーバーヘッドとなる。事前コンパイルで可能な、高度で時間のかかる最適化を行うことは許されない。これは、実行速度を向上させるためにコンパイルするのだから、あまり時間がかかっては意味がないためである。事前のコンパイルと比べてこのような不利な点を持ちながらも、JIT方式が有用なのは、実行時にコンパイルを行うことでオペレーティングシステムやCPUに依存しないソースコードや中間コードの状態でソフトウェアを配布することができるからである。JITを装備した処理系は、表面上はインタプリタとして動作するが、内部でコンパイルを行い、メモリ上に生成した機械語のコードが実行されるため、インタプリタと比べると実行速度を向上することができる。この意味で、JITはCPUやOSに依存しない実行形式を配布できる、というインタプリタの利点を保ったまま、実行速度が遅い、という欠点を克服しようとするものといえる。Compilation)[編集]上のようなJITコンパイラの短所を補うためのJITコンパイルの一方式として適応的コンパイルという方式がある。これは、起動当初はインタプリタとして実行し、よく呼び出されるメソッドや繰り返し実行されるコードの検出(プロファイリング)を行い、そのようなコードのみをコンパイルする、というものである。Compilation)と呼ぶ。一般にプログラムの実行においてその実行時間の大半はプログラム中のごく一部において費やされる、という経験則がある(実際の比率については状況に依存するが、典型的にはコードの実行時間の80%は20%のコードにおいて費やされるといわれ、80-20の法則と呼ばれる)。それと似て、適応的コンパイルにおいては実行時間の大半が費やされるような、ボトルネックとなるコードのみをコンパイルすることで、起動時のオーバーヘッドや利用メモリ増大を抑えたうえで、効率よく実行速度を向上することができる。静的コンパイルでは得られない情報をも元にして最適化が行えるため、静的コンパイルより、むしろパフォーマンスが上がる場合もある。注意すべきは、企業のバッチ処理である。数百件以内といった少量レコードを処理するバッチジョブが、一日に何百本、何千本も走る企業が多い。いう場では、JITコンパイルを用いた場合、適応的コンパイルをしてさえも、ジョブの走り初めに、使われるユーザクラスさらにはコアクラスと呼ばれるような共通的なクラスのコンパイル処理がロード処理を伴いのべ何百回と行われる。処理件数が少ないので、使うクラス群の多くはコンパイル効果が出る前に、あるいはコンパイルさえされないうちにジョブ実行が終わってしまう。その結果、正味のユーザロジックよりこうした「オーバヘッド」の方が大きな比率を占める。CPUなどの資源が、いつも同様のプログラム群のコンパイルに消費されてしまい、待ちが生じて多重効果の妨げにもなる。処理件数によってJIT/AOTの有利不利が変わるが使い分ける仕組みは非常に作りにくい。(Javaについていえば)AOTコンパイラを通常適用しにくい。[独自研究?]これらの理由で、性能面ではマイナスな場面でも一般的な[独自研究?]JITコンパイラを使用していることがある。長時間バッチジョブおよびオンラインでは、JITコンパイラ、特に適応的コンパイルが概してフィットしている。[独自研究?]適応的コンパイルの最適化のために、何回実行されたらコンパイルするか、といったパラメタが用意されているコンパイラがある[要出典]。パラメタチューニングは万能ではないとしても重要である。[独自研究?]JITコンパイル方式の利点[編集]JITコンパイル方式と事前コンパイルの生成コードの質を比べると、前述のようにコンパイル時間に対する制約のためJIT方式の方が不利であるが、有利な点もある。それは、実行環境を知った上でそれに応じた生成コードの選択や最適化を行うことができるということである。インテルのx86CPUを例にとって見ると、IA-32アーキテクチャの範囲内でもそれぞれの世代でさまざまに命令が拡張されてきているが、アプリケーションコードの後方互換性を保持する場合、実行バイナリ中では80386と互換の命令しか使うことができない。PentiumのMMX命令を含んだコードは80386やPentiumでは実行できない。JIT方式では、CPUがMMXをサポートしているならMMX命令を使ったコードを生成し、そうでなければ多少効率の悪いPentiumの命令の範囲内での実行を行う、ということができる。実行環境におけるキャッシュやメモリのサイズ、速度特性なども実行時にならないと最終的にはわからない。JITコンパイル方式では実際に走行しているCPUやメモリの情報を知ることができるため、それに応じたコードを生成することができ、事前コンパイルよりも優れたコードを生成できる可能性がある。応用[編集]JIT処理はJava技術の普及に伴い広範囲に使われるようになったが、JavaのHotSpot技術はSunにおけるSelf言語での動的コンパイル技術研究に基づいており、それに先立つ商用Smalltalk処理系でもJITコンパイル技術は確立されていた。JIT技術はトランスメタ社によるCrusoeでx86コードからCrusoeのVLIW命令への変換に用いられている。適応的コンパイル技術はDEC社によるFX!32技術でも用いられていた。Microsoft社による.NETプラットフォームも当初からJITによる実行を前提に設計されている。JavaのJITコンパイラ[編集]Symantec社によるsymjitおよびBorland社によるJITコンパイラは初期の主要なJITコンパイラであった。Microsystems自身によるHotSpotコンパイラは本格的に適応的コンパイル方式を採用したJIT処理系である。Hotspot以降はJITコンパイラ部分のインタフェースが規定されており、JITコンパイルエンジン部分を差し替えることができるようになった。JDK、BEAによるJRockitはいずれも適応的コンパイルを行う独自のJIT処理系を持っている。後者は特にx86に特化して実行効率を高めている。学術的なものとしては、首藤によるShuJITや、富士通研究所と東京工業大学によるリフレクション機能を扱うOpenJITなどがある。JavaScriptのJITコンパイラ[編集]近年の主要なウェブブラウザはJavaScriptのエンジンにJITコンパイラを搭載し、高速に処理できるようになっている。10.1以降のウェブブラウザに搭載されている。変数の型は統計的には安定しているという事実を使い、実行時の変数に代入された値の統計データから、変数に型を割り振ることにより、JITコンパイラが実現し、高速にJavaScriptを処理できるようになった[1]。3.5のように、事前に一度インタプリタで実行して、その情報を元に型を割り振りながらJITコンパイルするタイプなどがある。どちらのタイプであっても、型が安定しているケースは、高速に実行できるようになっている。JavaScriptにおいて、型が安定しているというのは、オブジェクトについては、プロパティが追加されていないという意味も含む。プロパティアクセスの時に、まず、型が期待通りの型であるかチェックし、もし、そうならば、プロパティからそれが指し示す番地へはC言語の構造体のように定数を足し算するだけで求まる。(日時は個人設定で未設定ならばUTC)。表示-継承ライセンスの下で利用可能です。追加の条件が適用される場合があります。詳細は利用規約を参照してください。Cookieに関する声明モバイルビュ。