1.0.39.8: Inline-compare more character codes on SB-UNICODE PPC.
[sbcl.git] / doc / manual / efficiency.texinfo
index de905ae..9b7cfd6 100644 (file)
@@ -4,11 +4,69 @@
 @cindex Efficiency
 
 @menu
 @cindex Efficiency
 
 @menu
+* Slot access::
 * Dynamic-extent allocation::
 * Modular arithmetic::
 * Dynamic-extent allocation::
 * Modular arithmetic::
+* Global and Always-Bound variables::
 * Miscellaneous Efficiency Issues::
 @end menu
 
 * Miscellaneous Efficiency Issues::
 @end menu
 
+@node  Slot access
+@comment  node-name,  next,  previous,  up
+@section Slot access
+@cindex Slot access
+
+@subsection Structure object slot access
+
+Structure slot accessors are efficient only if the compiler is able to
+open code them: compiling a call to a structure slot accessor before
+the structure is defined, declaring one @code{notinline}, or passing
+it as a functional argument to another function causes severe
+perfomance degradation.
+
+@subsection Standard object slot access
+
+The most efficient way to access a slot of a @code{standard-object} is
+by using @code{slot-value} with a constant slot name argument inside a
+@code{defmethod} body, where the variable holding the instance is a
+specializer parameter of the method and is never assigned to. The cost
+is roughly 1.6 times that of an open coded structure slot accessor.
+
+Second most efficient way is to use a CLOS slot accessor, or
+@code{slot-value} with a constant slot name argument, but in
+circumstances other than specified above. This may be up to 3 times as
+slow as the method described above.
+
+Example:
+
+@lisp
+(defclass foo () ((bar)))
+
+;; Fast: specializer and never assigned to
+(defmethod quux ((foo foo) new)
+  (let ((old (slot-value foo 'bar)))
+    (setf (slot-value foo 'bar) new)
+    old))
+
+;; Slow: not a specializer
+(defmethod quux ((foo foo) new)
+  (let* ((temp foo)
+         (old (slot-value temp 'bar)))
+    (setf (slot-value temp 'bar) new)
+    old))
+
+;; Slow: assignment to FOO
+(defmethod quux ((foo foo) new)
+  (let ((old (slot-value foo 'bar)))
+    (setf (slot-value foo 'bar) new)
+    (setf foo new)
+    old))
+@end lisp
+
+Note that when profiling code such as this, the first few calls to the
+generic function are not representative, as the dispatch mechanism is
+lazily set up during those calls.
+
 @node  Dynamic-extent allocation
 @comment  node-name,  next,  previous,  up
 @section Dynamic-extent allocation
 @node  Dynamic-extent allocation
 @comment  node-name,  next,  previous,  up
 @section Dynamic-extent allocation
@@ -35,14 +93,14 @@ useful. At present, SBCL implements stack allocation for
 @code{&rest} lists, when these are declared @code{dynamic-extent}.
 
 @item
 @code{&rest} lists, when these are declared @code{dynamic-extent}.
 
 @item
-@code{cons}, @code{list} and @code{list*}, when the result is bound to
-a variable declared @code{dynamic-extent}.
+@code{cons}, @code{list}, @code{list*}, and @code{vector} when the
+result is bound to a variable declared @code{dynamic-extent}.
 
 @item
 simple forms of @code{make-array}, whose result is bound to a variable
 declared @code{dynamic-extent}: stack allocation is possible only if
 
 @item
 simple forms of @code{make-array}, whose result is bound to a variable
 declared @code{dynamic-extent}: stack allocation is possible only if
-the resulting array is one-dimensional, and the call has no keyword
-arguments with the exception of @code{:element-type}.
+the resulting array is known to be both simple and one-dimensional,
+and has a constant @code{:element-type}.
 
 @strong{Note}: stack space is limited, so allocation of a large vector
 may cause stack overflow. For this reason potentially large vectors,
 
 @strong{Note}: stack space is limited, so allocation of a large vector
 may cause stack overflow. For this reason potentially large vectors,
@@ -63,11 +121,11 @@ user-defined structures when the structure constructor defined using
 call to the constructor is bound to a variable declared
 @code{dynamic-extent}.
 
 call to the constructor is bound to a variable declared
 @code{dynamic-extent}.
 
-@strong{Note:} structures with ``raw'' slots can currently be
+@strong{Note}: structures with ``raw'' slots can currently be
 stack-allocated only on x86 and x86-64.
 
 @item
 stack-allocated only on x86 and x86-64.
 
 @item
-all of the above when they appear as initial parts if another
+all of the above when they appear as initial parts of another
 stack-allocated object.
 
 @end itemize
 stack-allocated object.
 
 @end itemize
@@ -166,6 +224,36 @@ argument. ``Good'' widths are 32 on HPPA, MIPS, PPC, Sparc and x86 and
 64 on Alpha.  While it is possible to support smaller widths as well,
 currently this is not implemented.
 
 64 on Alpha.  While it is possible to support smaller widths as well,
 currently this is not implemented.
 
+@node  Global and Always-Bound variables
+@comment  node-name,  next,  previous,  up
+@section Global and Always-Bound variables
+
+@include macro-sb-ext-defglobal.texinfo
+
+@deftp {Declaration} sb-ext:global
+
+Syntax: @code{(sb-ext:global symbol*)}
+
+Only valid as a global proclamation.
+
+Specifies that the named symbols cannot be proclaimed or locally
+declared @code{special}. Proclaiming an already special or constant
+variable name as @code{global} signal an error. Allows more efficient
+value lookup in threaded environments in addition to expressing
+programmer intention.
+@end deftp
+
+@deftp {Declaration} sb-ext:always-bound
+
+Syntax: @code{(sb-ext:always-bound symbol*)}
+
+Only valid as a global proclamation.
+
+Specifies that the named symbols is always bound. Inhibits @code{makunbound}
+of the named symbols. Proclaiming an unbound symbol as @code{always-bound} signals
+an error. Allows compiler to elide boundness checks from value lookups.
+@end deftp
+
 @node  Miscellaneous Efficiency Issues
 @comment  node-name,  next,  previous,  up
 @section Miscellaneous Efficiency Issues
 @node  Miscellaneous Efficiency Issues
 @comment  node-name,  next,  previous,  up
 @section Miscellaneous Efficiency Issues