真のコンパイラとは、テキスト・ソースを実行可能なコードの断片すなわちOBJECTファイルに変換するツールのことだ。
実行可能なプログラムファイルも作れるが、それはリンカーの仕事で、(つまりリンカーを呼び出しているだけ(大笑))
- ブートストラップ・コード
- OBJECTファイル
- ライブラリィ・ファイル
の3つを1つのファイルにする。
なぜ、コンパイラとリンカーが分かれているのかと云えば、
コンパイラーは特定の言語専用なツールだが、リンカーはどのコンパイラーのOBJECTファイルでも(大抵)は扱えるシロモノなので、使いまわしができるリンカーをコンパイラーに組み込むのは馬鹿にしかできない無駄な仕事だからだ。
※もちろん、そんなバカな奴は世界中にいっぱいいる。
初期のOSは面倒くさがりで、単にマージするだけで、実行できるようにしていたが、そんなことでは、OBJファイル同士で参照したりするのが大変なので、リンカーが参照アドレス表(シンボリック・リンク・テーブル)なども作ったりする。
このテーブルがあるからこそ、ソースレベルデバッグやブレークポイントをデバッガで使えるのだ。
※もちろん、OBJECTファイルにデバッグ用コードが含まれているが、それだけでは当のOBJECTファイルのアドレスが判らない。
そして、実行可能なプログラムファイルとはCPUにブートストラップ・コードを咥えさせれば、後は勝手に夢中になるようなファイルのことである。
妙なファイルに思えるかもしれないが、メッセンジャーRNAにリボゾームがくっ付いて、アミノ酸の合成するのに似ている。
しかし、今では、コンパイラもインタープリタもあまり変わり映えしない。余りにも扱うライブラリィが巨大で、どっちも起動時間が長くなっている。
故に純粋なコンパイラは非常に遅いが、その代り出来上がった実行コードは、インタープリタが毎度毎度モサモサと解析しながら処理するよりは動きが速い。
速度比は、こんな感じ。
BAT << WSH << EXCELマクロの速度 << Java << (絶対に越えられない壁) << VISUAL-BASIC << C# << C++ << C
※この式から、左側ではループは組まない方が速い。
※ループを組む部分だけ右側にすると処理速度は軽く10倍は速くなる。ことが判る。
※余談だがWSHでデータベースのSQLを実行させたら、データを吐き出す部分はC#あたりでOCX化し、レコードセットを渡してやらせた方が速い。EXCELも同じ。
※同様にJavaでもループ部分だけC++コンパイラで組めばよい。てか、Javaのランタイムはそうやって速度を稼いでいる。だから、ResultSetでループするJavaソースはサンプルでしかない。
だから、高速なコンパイラとは低速なコンパイラの中では高速と云う比喩であって、本当に速い訳が無い。
ただし、A+B=C程度のライブラリしか参照しない場合に限っては、高速化されているものが多い。※多分にベンチマーク仕様。
大体、真に高速なコンパイラがあればLinuxのカーネルのコンパイルを昼寝して待つ必要なぞないのだからな。(大笑
しかし、よく使うライブラリィのヘッダーをプリ・コンパイルする手法を用いて、見かけ上早くする方法は、既に数十年前からMSがやっている。
但し、コンパイルのオプションを変えると(MTなど)、再度プリ・コンパイルからやり直しが必要になる。
ps.
なんとなく書き殴ってみた。