Lisp HUG Maillist Archive

Optimizing Lisp

I have some code I'm trying to optimize, and I have some questions about 
the kinds of optimizations LispWorks can do with (speed 3) (safety 0) 
(debug 0) etc.

 * Does it help to (declare (type ...)) of a symbol (either lexical or 
special) if that symbol refers to an obj (either struct or CLOS)?

 * Does it help to (declare (ftype ...)) for functions? Is it possible for 
methods?

 * Does it help to declare :type for CLOS slots?

 * Is it insane to use CLOS objects and methods when speed is important? 
The alternative would be defuns with either case or typecase, which is 
theoretically the same but probably much easier for Lisp to optimize--esp 
since there's no multi-method overhead, etc.

I've been running timing tests and I've been looked at disassembled code, 
but I'm learning as I go and official feedback would help.

ps: For this project I've ported tens of thousands of lines of code to 
just a couple thousand lines of Lisp. The reason for the dramatic 
reduction is that the old code basically implemented an interpreter for 
user-defined formulas. In the Lisp version everything--including 
user-defined formulas--runs as native code. Performance is important 
because one run of the program can calculate tens of millions of values. 
Native code should make it smaller *and* faster... But only, I think, if 
optimizations are in place. The interpreter was an interpreter, but it was 
reasonably well optimized...


Re: Optimizing Lisp

Unable to parse email body. Email id is 1959

Re: Optimizing Lisp

Thanks, Dave. That helps. Some follow-up below...

owner-lisp-hug@xanalys.com wrote on 03/03/2004 03:05:43 PM:

>     * Does it help to (declare (ftype ...)) for functions? Is 
> it possible for 
>    methods?
> 
> FTYPE decls are used by the compiler to determine the result type of a
> function call (e.g. for arithmetic optimizations on that value).  They
> don't affect the function definitions themselves.

Yes, I understand the bit about the result type; I just wanted to confirm 
that LispWorks did indeed pay attention to it. But as to the function 
*definitions*, wouldn't declaring the argument types help? Wouldn't that 
be equivalent to putting a (declare (type ...)) inside the function for 
the arguments? Or do you still need the internal (declare ...) to optimize 
the definition? (Btw, above I meant "declaim" rather than "declare".)

One other question: I have a struct that contains a symbol and a 
double-float. If I declare a vector of these things and the type of the 
vector, will the double-float be unboxed? (In my disassembled constructor 
I see a call to "SYSTEM::RAW-FAST-BOX-FLOAT".) There will be a lot of 
these structs, and I want to make them memory-efficient.


Re: Optimizing Lisp

Unable to parse email body. Email id is 1963

Re: Optimizing Lisp

Unable to parse email body. Email id is 1964

Re: Optimizing Lisp

> Yes, in theory FTYPE declarations could provide this information, but
> in LispWorks you currently need the internal (declare ...) forms to
> optimize the definition.

> No, unboxed double-floats can only be stored in local variables and
> double-float arrays. Perhaps you can store the data in two separate 
> arrays?

Excellent! Thanks, that's exactly the kind of info I was looking for.

> You should look at FIXNUM-SAFETY and FLOAT declarations, if these are
> numerical calculations.

They are. This is what I'm using:

        (debug 0) (float 0) (safety 0) (speed 3) (space 0) 
(compilation-speed 0)

If I add (fixnum-safety 0) or (fixnum-safety 1) I get the errors below. 
The second one is particularly interesting! (In the first error output you 
see part of a trace on make-num-valid.)

=================
(fixnum-safety 0)
=================

0 PBVIEWS::MAKE-VALID-NUM > ...
  >> ARG-0 : #<pumpkin, tag 0 40D007D8>

Error: In SYSTEM::COERCE-TO-DOUBLE-FLOAT of (#<pumpkin, tag 0 40D007D8>) 
arguments should be of type NUMBER.
  1 (continue) Return a value to use.
  2 Supply a new argument.
  3 Try loading pbviews-test again.
  4 Give up loading pbviews-test.
  5 Try loading another file instead of pbviews-test.
  6 (abort) Return to level 0.
  7 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed,  or :? for other 
options

CL-USER 37 : 1 > :bb
#<PACKAGE COMMON-LISP-USER>

Condition: In SYSTEM::COERCE-TO-DOUBLE-FLOAT of (#<pumpkin, tag 0 
40D007D8>) arguments should be of type NUMBER.
Call to SYSTEM::SINGLE-ARG-BAD-TYPE (offset 403)
  SYSTEM::FN-NAME : SYSTEM::COERCE-TO-DOUBLE-FLOAT
  SYSTEM::ARG     : #<***error while printing condition type 
CONDITIONS:SYSTEM-ERROR>
  TYPE            : :DONT-KNOW

Call to Anonymous compiled function #<function 2071BBBA> (offset 21)
....

=================
(fixnum-safety 1)
=================

Error: In + of (10.0 33.0) arguments should be of type NUMBER.
  1 (continue) Return a value to use.
  2 Supply new arguments to use.
  3 Try loading pbviews-test again.
  4 Give up loading pbviews-test.
  5 Try loading another file instead of pbviews-test.
  6 (abort) Return to level 0.
  7 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed,  or :? for other 
options

CL-USER 34 : 1 > :bb
#<PACKAGE COMMON-LISP-USER>

Condition: In + of (10.0 33.0) arguments should be of type NUMBER.
Call to SYSTEM::ARGS-TO-BINARY-ARITHMETIC-FN-NOT-OF-TYPE (offset 528)
  SYSTEM::FN-NAME : +
  SYSTEM::ARG1    : 10.0
  SYSTEM::ARG2    : 33.0
  TYPE            : :DONT-KNOW

Call to PBVIEWS::NUM-ADD (offset 190)
....


Updated at: 2020-12-10 08:57 UTC