cl: Efficiency Concerns

 
 Appendix A Efficiency Concerns
 ******************************
 
 A.1 Macros
 ==========
 
 Many of the advanced features of this package, such as ‘cl-defun’,
 ‘cl-loop’, etc., are implemented as Lisp macros.  In byte-compiled code,
 these complex notations will be expanded into equivalent Lisp code which
 is simple and efficient.  For example, the form
 
      (cl-incf i n)
 
 is expanded at compile-time to the Lisp form
 
      (setq i (+ i n))
 
 which is the most efficient ways of doing this operation in Lisp.  Thus,
 there is no performance penalty for using the more readable ‘cl-incf’
 form in your compiled code.
 
    _Interpreted_ code, on the other hand, must expand these macros every
 time they are executed.  For this reason it is strongly recommended that
 code making heavy use of macros be compiled.  A loop using ‘cl-incf’ a
 hundred times will execute considerably faster if compiled, and will
 also garbage-collect less because the macro expansion will not have to
 be generated, used, and thrown away a hundred times.
 
    You can find out how a macro expands by using the ‘cl-prettyexpand’
 function.
 
  -- Function: cl-prettyexpand form &optional full
      This function takes a single Lisp form as an argument and inserts a
      nicely formatted copy of it in the current buffer (which must be in
      Lisp mode so that indentation works properly).  It also expands all
      Lisp macros that appear in the form.  The easiest way to use this
      function is to go to the ‘*scratch*’ buffer and type, say,
 
           (cl-prettyexpand '(cl-loop for x below 10 collect x))
 
      and type ‘C-x C-e’ immediately after the closing parenthesis; an
      expansion similar to:
 
           (cl-block nil
                (let* ((x 0)
                       (G1004 nil))
                  (while (< x 10)
                    (setq G1004 (cons x G1004))
                    (setq x (+ x 1)))
                  (nreverse G1004)))
 
      will be inserted into the buffer.  (The ‘cl-block’ macro is
      expanded differently in the interpreter and compiler, so
      ‘cl-prettyexpand’ just leaves it alone.  The temporary variable
      ‘G1004’ was created by ‘cl-gensym’.)
 
      If the optional argument FULL is true, then _all_ macros are
      expanded, including ‘cl-block’, ‘cl-eval-when’, and compiler
      macros.  Expansion is done as if FORM were a top-level form in a
      file being compiled.
 
      Note that ‘cl-adjoin’, ‘cl-caddr’, and ‘cl-member’ all have
      built-in compiler macros to optimize them in common cases.
 
 A.2 Error Checking
 ==================
 
 Common Lisp compliance has in general not been sacrificed for the sake
 of efficiency.  A few exceptions have been made for cases where
 substantial gains were possible at the expense of marginal
 incompatibility.
 
    The Common Lisp standard (as embodied in Steele’s book) uses the
 phrase “it is an error if” to indicate a situation that is not supposed
 to arise in complying programs; implementations are strongly encouraged
 but not required to signal an error in these situations.  This package
 sometimes omits such error checking in the interest of compactness and
 efficiency.  For example, ‘cl-do’ variable specifiers are supposed to be
 lists of one, two, or three forms; extra forms are ignored by this
 package rather than signaling a syntax error.  Functions taking keyword
 arguments will accept an odd number of arguments, treating the trailing
 keyword as if it were followed by the value ‘nil’.
 
    Argument lists (as processed by ‘cl-defun’ and friends) _are_ checked
 rigorously except for the minor point just mentioned; in particular,
 keyword arguments are checked for validity, and ‘&allow-other-keys’ and
 ‘:allow-other-keys’ are fully implemented.  Keyword validity checking is
 slightly time consuming (though not too bad in byte-compiled code); you
 can use ‘&allow-other-keys’ to omit this check.  Functions defined in
 this package such as ‘cl-find’ and ‘cl-member’ do check their keyword
 arguments for validity.
 
 A.3 Compiler Optimizations
 ==========================
 
 Changing the value of ‘byte-optimize’ from the default ‘t’ is highly
 discouraged; many of the Common Lisp macros emit code that can be
 improved by optimization.  In particular, ‘cl-block’s (whether explicit
 or implicit in constructs like ‘cl-defun’ and ‘cl-loop’) carry a fair
 run-time penalty; the byte-compiler removes ‘cl-block’s that are not
 actually referenced by ‘cl-return’ or ‘cl-return-from’ inside the block.