1.0.41.42: ppc: Documentation and NEWS updates for threading.
[sbcl.git] / doc / manual / efficiency.texinfo
index de905ae..6820e77 100644 (file)
@@ -4,15 +4,74 @@
 @cindex Efficiency
 
 @menu
+* Slot access::
 * Dynamic-extent allocation::
 * Modular arithmetic::
+* Global and Always-Bound variables::
 * 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
-@cindex Dynamic-extent declaration
+@cindex @code{dynamic-extent} declaration
+@cindex declaration, @code{dynamic-extent}
 
 SBCL has limited support for performing allocation on the stack when a
 variable is declared @code{dynamic-extent}. The @code{dynamic-extent}
@@ -35,21 +94,31 @@ useful. At present, SBCL implements stack allocation for
 @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}.
+@findex @cl{cons}
+@findex @cl{list}
+@findex @cl{list*}
+@findex @cl{vector}
+@code{cons}, @code{list}, @code{list*}, and @code{vector} when the
+result is bound to a variable declared @code{dynamic-extent}.
 
 @item
+@findex @cl{make-array}
 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}.
 
+@cindex Safety optimization quality
 @strong{Note}: stack space is limited, so allocation of a large vector
 may cause stack overflow. For this reason potentially large vectors,
 which might circumvent stack overflow detection, are stack allocated
 only in zero @code{safety} policies.
 
 @item
+@findex @cl{flet}
+@findex @cl{labels}
+@cindex @code{safety} optimization quality
+@cindex optimization quality, @code{safety}
 closures defined with @code{flet} or @code{labels}, with a bound
 @code{dynamic-extent} declaration. Closed-over variables, which are
 assigned to (either inside or outside the closure) are still allocated
@@ -63,11 +132,11 @@ user-defined structures when the structure constructor defined using
 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
-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
@@ -131,7 +200,7 @@ closure, even when the closure is not declared @code{dynamic-extent}.
 @cindex Modular arithmetic
 @cindex Arithmetic, modular
 @cindex Arithmetic, hardware
-
+@findex @cl{logand}
 Some numeric functions have a property: @var{N} lower bits of the
 result depend only on @var{N} lower bits of (all or some)
 arguments. If the compiler sees an expression of form @code{(logand
@@ -166,6 +235,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.
 
+@node  Global and Always-Bound variables
+@comment  node-name,  next,  previous,  up
+@section Global and Always-Bound variables
+
+@include macro-sb-ext-defglobal.texinfo
+
+@deffn {Declaration} @sbext{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 deffn
+
+@deffn {Declaration} @sbext{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 deffn
+
 @node  Miscellaneous Efficiency Issues
 @comment  node-name,  next,  previous,  up
 @section Miscellaneous Efficiency Issues
@@ -199,6 +298,10 @@ points to keep in mind.
 @itemize
 
 @item
+@findex @cl{let}
+@findex @cl{let*}
+@findex @cl{setq}
+@findex @cl{setf}
 The CMUCL manual doesn't seem to state it explicitly, but Python has a
 mental block about type inference when assignment is involved. Python
 is very aggressive and clever about inferring the types of values