Go to the first, previous, next, last section, table of contents.

バイトコンパイル

GNU Emacs Lisp は、関数を(書かれたままの)テキストから、 (より効率良く実行でき る) バイトコードと呼ばれる(特別な)形式にトランスレートするコンパイラを持ってい ます。このコンパイラは(各々の)関数定義をバイトコードで置き換えます。バイトコー ドファイルをロードすると、 (その)ファイルで定義された関数はバイトインタープリ タで評価されます。

(各々の)関数定義は byte-compile 関数でバイトコンパイルされます。ファイル全体を byte-compile-file でコンパイルすることもできます。複数のファイルを byte- recompile-directory や batch-byte-compule でバイトコンパイルすることもできま す。

バイトコンパイルしたコードは、そのマシンのハードウェアで(直接)実行されるのでは なく、 (コンパイルされたほとんどのコードを実行できる) バイトインタープリタで評 価されるため、バイトコードは、 (再コンパイルしなくても)マシンからマシンに移す ことができます。

バイトコンパイルされた関数は C で書かれた primitive 関数ほど効率的ではありませ んが、インタープリットされるものよりはずっと速く走ります。 (粗く)比較するため には、以下に示した例を参照して下さい。

マクロを用いたコードをバイトコンパイルする場合は注意して下さい。マクロは(全 て)、用いる前に定義されてなくてはいけません。詳細に関してはセクション 11.2 [defmacro]、ページ 93 を参照して下さい。

      (defun silly-loop (n)
        (setq t1 (current-time-string))
        (while (> n 0)
          (setq n (1- n)))
        (setq t2 (current-time-string))
        (list t1 t2))
      => silly-loop
      (silly-loop 100000)
      => ("Thu Oct 8 20:32:21 1987" "Thu Oct 8 20:34:42 1987") ; 2 分 21 秒
      (byte-compile 'silly-loop)
      => [Compiled code not shown]
      (silly-loop 100000)
      => ("Thu Oct 8 20:40:47 1987" "Thu Oct 8 20:41:17 1987") ; 30 秒

この例では、インタープリットされたコードは実行に 2:21 要していますが、バイトコ ンパイルされたコードは 0:30 しか要していません。この結果はバイトコンパイルの効 果をよく示しています。しかし、これは呼ばれる関数によって大きく変化します。

Function: byte-compile symbol

この関数は、 symbol の関数定義をバイトコンパイルし、コンパイルした結果で (前の)定義を置き換えます。 symbol の関数セルは関数に対する(実際の)コードを 含んでなくてはいけません。コンパイラは他のシンボルへの間接は扱いません。

Command: byte-compile-file filename

この関数は、 filename という名前の Lisp コードのファイルをコンパイルし、バ イトコードのファイルを作ります。出力ファイルの名前は filename の後ろに "c" を付けたものになります。

インタラクティブに呼ばれた場合、ファイル名を求め(エコーアリアに)プロンプト を出します。

  lewis@slug[3] % ls -l push*
  -rw-r--r-- 1 lewis     0        791 Oct   5 20:31 push.el
  (byte-compile-file "~/emacs/push.el")
  => t
  lewis@slug[3] % ls -l push*
  -rw-r--r-- 1 lewis     0        791 Oct   5 20:31 push.el
  -rw-r--r-- 1 lewis     0        638 Oct   8 20:25 push.elc

Command: byte-recompile-directory directory flag

この関数は、 directory 中の (再)コンパイルを必要とする (全) `.el' ファイル を (再)コンパイルします。(`.elc' ファイルが存在している場合も)それが `.el' ファイルより古い場合、(再)コンパイルを必要とします。

   `.el' ファイルが存在していて、それに対する `.elc' ファイルが存在しない場
  合、 flag を調べ、これが nil の場合、このファイルを無視します。 non-nil の
  場合、(ユーザーに対し)このファイルをコンパイルするか否かを尋ねます。

インテラクティブに呼ばれた場合、 directory を求め(エコーエリアに)プロンプ トを出し、 flag は未処理のプレフィックスアーギュメントになります。

Function: batch-byte-compile

この関数は、コマンド行の(残りの)ファイルに対し byte-compile-file を走らせ ます。この関数は終了時に Emacs を kill するため、 (Emacs の)バッチ実行での み用いられます。前のファイルのコンパイルでエラーが生じても、各々のファイル に対し処理を行ないます(もちろん、エラーの生じたファイルに対してはコンパイ ルしたコードは出力しません)。

  lewis@slug[6] % emacs -batch -f batch-byte-compile $emacs/ ~/*.el"

Function: byte-code

これは、(実際に)バイトコードをインタープリットする関数です。 (コンパイルさ れた関数に対し) Lisp evaluator から呼ばれます。 (通常) ユーザーコードから 呼ばれることはありません。

Function: disassemble object &optional stream

この関数は、 object を逆アセンブルしたコードを print します。 stream が与 えられた場合、出力はそこに向けられます。与えられない場合、逆アセンブルした コードを標準出力に print します。 object は、関数名、lambda 式、symbol- function の返す(任意の)関数オブジェクトでありえます。

object がまだコンパイルされてない場合、コンパイルは行ないますが、 (再)定義 は行ないません。

  (disassemble 'silly-loop)
  ->
  byte code for silly-loop:
   args: (n)
  0   constant current-time-string
  1   call     0
  2   dup
  3   varset   t1
  4   discard
  5   varref   n
  6   constant 0
  7   gtr
  8   goto-if-nil-else-pop 19
  11  varref   n
  12  sub1
  13  dup
  14  varset   n
  15  discard
  16  goto     5
  19  discard
  20  constant current-time-string
  21  call     0
  22  cup
  23  varset   t2
  24  discard
  25  varref   t1
  26  varred   t2
  27  list2
  28  return
  => nil


Go to the first, previous, next, last section, table of contents.