the previous chapterで述べたバイトコンパイルに加えて、EmacsではオプションでLisp関数定義をネイティブコード(native code)として知られている真のコンパイル済みコードにコンパイルすることもできます。この機能はGCCディストリビューションの一部であるlibgccjitを使用しており、そのライブラリー使用のサポートと共にEmacsがビルドされている必要があります。更にネイティブコンパイルされたLispコードを利用可能にするために、システムにGCCとBinutils(アセンブラとリンカ)がインストールされている必要があります。
Emacsのカレントプロセスでネイティブコンパイル済みLispコードの生成およびロードが可能かどうか判断するには、native-comp-available-p
(ネイティブコンパイル関数を参照)を呼び出してください。
バイトコンパイル済みコードとは異なり、ネイティブコンパイル済みLispコードはマシンのハードウェアにより直接実行されるので、ホストCPUが提供できる最高スピードで実行されます。このスピードアップの結果は一般的にはそのLispコードが何を行うかに依りますが、対応するバイトコンパイル済みコードに比べて、通常は2.5から5倍高速になります。
一般的に異なるシステム間ではネイティブコードに互換性はないので、あるマシンから別のマシンへのネイティブコンパイル済みコードの可搬性はありません。ネイティブコンパイル済みコードはそれを生成したのと同じマシン、もしくは類似のマシン(同一のCPUおよびランタイムライブラリー)でのみ使用できます。ネイティブコンパイル済みコードの可搬性は、共有ライブラリー(.soや.dllのファイル)の可搬性と同様です。
ネイティブコンパイル済みコードのライブラリーにはEmacs Lispプリミティブ(関数とは?を参照)とそれらの呼び出し規約に関して重大な依存性が含まれているので、Emacsは通常はバージョンの異なるEmacsが生成したネイティブコンパイル済みコードをロードしません。同一のLispコードで異なるバージョンのEmacsがネイティブコンパイルしたコードは、ネイティブコンパイル済みライブラリーをそのバージョンのEmacsだけがロードできる一意なファイル名で生成します。しかし一意なファイル名の使用により、複数の異なるバージョンのEmacsによりネイティブコンパイルされた同じLispライブラリーの複数のバージョンの同一ディレクトリーへの配置が有効になります。
ファイルローカル変数としてno-byte-compile
に非nil
をバインドしても、そのファイルのネイティブコンパイルが無効になります。加えて同様の変数no-native-compile
は、ファイルのネイティブコンパイルだけを無効にします。no-byte-compile
とno-native-compile
の両方が指定された場合には、前者が優先されます。
ネイティブコンパイルによるuser-emacs-directory
のサブディレクトリー内の*.elnファイルへの結果の書き込みを防がなければならない場合もあるかもしれません。これはnative-comp-eln-load-path
の値を変更するか(ネイティブコンパイル変数を参照)、あるいは環境変数HOME
が一時的に既存ディレクトリー以外を指すようにすることで行うことができます。後者のテクニックはEmacsがトランポリン(trampolines)を生成する必要がある場合(Lispコード内においてLispプリミティブをネイティブにコンパイルするためにアドバイスまたは再定義する際に用いられる)には、依然として少数の*.elnファイルを生成するかもしれないことに注意が必要です。trampolinesを参照してください。かわりにstartup-redirect-eln-cache
関数を使用してデフォルト以外のディレクトリーに*.elnファイルを書き込むよう指定できます。ネイティブコンパイル関数を参照してください。