1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1//EN"
3 "http://www.oasis-open.org/docbook/xml/4.1/docbookx.dtd" [
4 <!ENTITY % myents SYSTEM "entities.inc">
8 <chapter id="efficiency"><title>Efficiency</title>
10 <para>FIXME: The material in the &CMUCL; manual about getting good
11 performance from the compiler should be reviewed, reformatted in
12 DocBook, lightly edited for &SBCL;, and substituted into this
13 manual. In the meantime, the original &CMUCL; manual is still 95+%
14 correct for the &SBCL; version of the &Python; compiler. See the
17 <listitem><para>Advanced Compiler Use and Efficiency Hints</para></listitem>
18 <listitem><para>Advanced Compiler Introduction</para></listitem>
19 <listitem><para>More About Types in Python</para></listitem>
20 <listitem><para>Type Inference</para></listitem>
21 <listitem><para>Source Optimization</para></listitem>
22 <listitem><para>Tail Recursion</para></listitem>
23 <listitem><para>Local Call</para></listitem>
24 <listitem><para>Block Compilation</para></listitem>
25 <listitem><para>Inline Expansion</para></listitem>
26 <listitem><para>Object Representation</para></listitem>
27 <listitem><para>Numbers</para></listitem>
28 <listitem><para>General Efficiency Hints</para></listitem>
29 <listitem><para>Efficiency Notes</para></listitem>
33 <para>Besides this information from the &CMUCL; manual, there are a
34 few other points to keep in mind.
36 <listitem><para>The &CMUCL; manual doesn't seem to state it explicitly,
37 but &Python; has a mental block about type inference when
38 assignment is involved. &Python; is very aggressive and clever
39 about inferring the types of values bound with <function>let</function>,
40 <function>let*</function>, inline function call, and so forth. However,
41 it's much more passive and dumb about inferring the types of
42 values assigned with <function>setq</function>, <function>setf</function>, and
43 friends. It would be nice to fix this, but in the meantime don't
44 expect that just because it's very smart about types in most
45 respects it will be smart about types involved in assignments.
46 (This doesn't affect its ability to benefit from explicit type
47 declarations involving the assigned variables, only its ability to
48 get by without explicit type declarations.)</para></listitem>
49 <!-- FIXME: Python dislikes assignments, but not in type
50 inference. The real problems are loop induction, closed over
51 variables and aliases. -->
52 <listitem><para>Since the time the &CMUCL; manual was written,
53 &CMUCL; (and thus &SBCL;) has gotten a generational garbage
54 collector. This means that there are some efficiency implications
55 of various patterns of memory usage which aren't discussed in the
56 &CMUCL; manual. (Some new material should be written about
57 this.)</para></listitem>
58 <listitem><para>&SBCL; has some important known efficiency problems.
59 Perhaps the most important are
61 <listitem><para>There is no support for the &ANSI;
62 <parameter>dynamic-extent</parameter> declaration, not even for
63 closures or <parameter>&rest</parameter> lists.</para></listitem>
64 <listitem><para>The garbage collector is not particularly
65 efficient.</para></listitem>
66 <listitem><para>Various aspects of the PCL implementation
67 of CLOS are more inefficient than necessary.</para></listitem>
73 <para>Finally, note that &CommonLisp; defines many constructs which, in
74 the infamous phrase, <quote>could be compiled efficiently by a
75 sufficiently smart compiler</quote>. The phrase is infamous because
76 making a compiler which actually is sufficiently smart to find all
77 these optimizations systematically is well beyond the state of the art
78 of current compiler technology. Instead, they're optimized on a
79 case-by-case basis by hand-written code, or not optimized at all if
80 the appropriate case hasn't been hand-coded. Some cases where no such
81 hand-coding has been done as of &SBCL; version 0.6.3 include
83 <listitem><para><literal>(reduce #'f x)</literal>
84 where the type of <varname>x</varname> is known at compile
85 time</para></listitem>
86 <listitem><para>various bit vector operations, e.g.
87 <literal>(position 0 some-bit-vector)</literal></para></listitem>
89 If your system's performance is suffering because of some construct
90 which could in principle be compiled efficiently, but which the &SBCL;
91 compiler can't in practice compile efficiently, consider writing a
92 patch to the compiler and submitting it for inclusion in the main
93 sources. Such code is often reasonably straightforward to write;
94 search the sources for the string <quote><function>deftransform</function></quote>
95 to find many examples (some straightforward, some less so).</para>
97 <sect1 id="modular-arithmetic"><title>Modular arithmetic</title>
99 Some numeric functions have a property: <varname>N</varname> lower bits of
100 the result depend only on <varname>N</varname> lower bits of (all or some)
101 arguments. If the compiler sees an expression of form <literal>(logand
102 exp mask)</literal>, where <varname>exp</varname> is a tree of such "good" functions
103 and <varname>mask</varname> is known to be of type <type>(unsigned-byte
104 w)</type>, where <varname>w</varname> is a "good" width, all intermediate results
105 will be cut to <varname>w</varname> bits (but it is not done for variables
106 and constants!). This often results in an ability to use simple
107 machine instructions for the functions.
114 (declare (type (unsigned-byte 32) x y))
115 (ldb (byte 32 0) (logxor x (lognot y))))
117 The result of <literal>(lognot y)</literal> will be negative and of
118 type <type>(signed-byte 33)</type>, so a naive implementation on a 32-bit
119 platform is unable to use 32-bit arithmetic here. But modular
120 arithmetic optimizer is able to do it: because the result is cut down
121 to 32 bits, the compiler will replace <function>logxor</function>
122 and <function>lognot</function> with versions cutting results to 32 bits, and
123 because terminals (here---expressions <literal>x</literal> and <literal>y</literal>)
124 are also of type <type>(unsigned-byte 32)</type>, 32-bit machine
125 arithmetic can be used.
128 <note><para> As of &SBCL; 0.8.5 "good" functions
129 are <function>+</function>, <function>-</function>; <function>logand</function>, <function>logior</function>,
130 <function>logxor</function>, <function>lognot</function> and their combinations;
131 and <function>ash</function> with the positive second argument. "Good" widths
132 are 32 on HPPA, MIPS, PPC, Sparc and X86 and 64 on Alpha. While it is
133 possible to support smaller widths as well, currently it is not