Careful use of the compiler optimize qualities described above or special declarations may significantly improve the performance of your code. However it is not recommended that you simply experiment with the effect of adding declarations. It is more productive to work systematically:
:explaindeclarations to make the compiler generate optimization hints, and
The most important tool for speeding up programs is the Profiler. You use the profiler to find the bottlenecks in the program, and then optimize these bottlenecks by helping the compiler to produce better code.
The remainder of this section describes some specific ways to produce efficient compiled code with LispWorks.
The full syntax of the
:explain declaration is documented in the reference entry for declare.
Various keywords allows you to see information about compiler transformations depending on type information, allocation of floats and bignums, floating point variables, function calls, argument types and so on. Here is a simple example:
Note: the LispWorks IDE allows you to distinguish compiler optimization hints from the other output of compilation, and also helps you to locate quickly the source of each hint. For more information see the chapter "The Output Browser" in the LispWorks IDE User Guide .
float allows generation of more efficient code using float numbers. It reduces allocation during float calculations. It is best used with safety 0. That is, you declare
(optimize (float 0) (safety 0)) as in this example:
debugis 3, or
cl:dynamic-extentallocation (so it is not really a tail call)
&key) parameters in the calling function.
cl:special specifies that a variable is special, that is it does not have lexical scope. This covers two cases: if the variable is bound in the dynamic environment (for example by
let*), then the value of that binding is used; otherwise the value in the global environment is used, if any. An error is signaled in safe code if there is no value in either environment. When
setq is used with a variable, the value in the dynamic environment is modified if the variable is bound in the dynamic environment, otherwise the value in the global environment is modified. Dynamic variables can have a different value in each thread because each thread has is own dynamic environment. The global environment is shared between all threads.
In SMP LispWorks access to special variables (excluding constants) is a little slower than in non-SMP LispWorks. It can be made to run faster by declarations of the symbol, normally by using by proclaim or declaim.
The speedup will be pretty small overall in most cases, because access to specials is usually a small part of a program. However, if the Profiler identifies some piece of code as a bottleneck, you will want to optimize it, and your optimizations may include proclamation of some variable as global or dynamic.
The three declarations described in this section are extensions to Common Lisp. All declare the symbol to be
cl:special, along with other information. These three declarations are mutually exclusive between themselves and
cl:special. That is, declaring a symbol with any of these declarations eliminates the other declaration:
hcl:special-globaldeclares that the symbol is never bound in the dynamic environment.
hcl:special-global is very useful, and because of the checks it is reasonably safe. It is useful not only for speed, but also to guard against unintentionally binding variables that should not be bound.
See also defglobal-parameter.
hcl:special-dynamicdeclares that the symbol is always bound in the dynamic environment when it is accessed.
hcl:special-fast-accessdeclares that a symbol should be "fast access".
The semantics of the declaration is the same as
cl:special, except that access to the variable is low safety. In addition, the compiler compiles access to the symbol in a way that speeds up the access, but also introduces a tiny reduction in the speed of the whole system. The balance between these effects is not obvious.
The macro analysing-special-variables-usage can be used to find symbols that may be proclaimed global, which can improve performance. analysing-special-variables-usage also helps to identify inconsistencies in the code.
)without any other arguments
make-foois an inline structure constructor. The default constructor is declared inline automatically when none of the
defstructslot initforms are calls to functions.
cl:delete-duplicates for lists when the test or test-not is one of a small set of known functions. These functions are currently
LispWorks User Guide and Reference Manual - 20 Sep 2017