From: Dennis Dunn
Subject: Simple question about optimize
Date: 
Message-ID: <2oVBa.88775$BA.29483827@twister.columbus.rr.com>
Hello,

I am having trouble understanding the use of (declaim). I have the following
form at the top of my file:

(declaim (optimize (speed 3) (safety 0))

CLHS says that when this appears at the top of a file that is being compiled
the delcaration is effective for the entire file.  However, there seems to
be no difference when I use (time) to profile the execution of my main form.
That is, the execution time is the same whether  I compile the file with the
(declaim) form or not.

My expectation was that my code would run a bit quicker with the (optimize)
form but that was not the case.  It could very well be that my code is so
simple that optimizing for speed=3 has no effect.  Any help in the learning
process is greatly appreciated.

I am using clisp on Windows with the emacs/ilisp setup as described in the
"Setting up an IDE with Emacs on Windows" document from the Common Lisp
Cookbook. (Very cool, btw.  Thanks.)  I also tried this with the Lispworks
personal edition with the same results.  When I used Lispworks, the message
from the compilation process tells me that the optimize settings were
safety=3 and speed=1.

Thanks for your help.

--dennis

From: Kent M Pitman
Subject: Re: Simple question about optimize
Date: 
Message-ID: <sfwhe7beng5.fsf@shell01.TheWorld.com>
"Dennis Dunn" <·····@insight.rr.com> writes:

> (declaim (optimize (speed 3) (safety 0))
> 
> CLHS says that when this

[presumably with one extra close paren]

> appears at the top of a file that is being compiled
> the delcaration is effective for the entire file.  However, there seems to
> be no difference when I use (time) to profile the execution of my main form.
> That is, the execution time is the same whether  I compile the file with the
> (declaim) form or not.

This depends on whether the particular implementation makes decisions based
on these criteria.  [i.e., a clisp implementor (not me) will probably have
to comment to give you the straight info--I'm just guessing based on what
I know of the spec and very limited use of clisp.]

The standard does not promise that an implementation will do so; what it does
is tell you that if you have a preference, this is the way to state it just
in case.

clisp is somewhat anomalous among the CL implementations because it is a 
byte-coded implementation, and consequently its notion of what it is to 
optimize something may be very different than that of another implementation.

For example, Symbolics never did anything with safety declarations because
the Symbolics hardware was always doing safety checks in hardware, and 
sometimes omitting these was not even possible, but mostly it was unnecessary
because it didn't slow things down.  I don't know the clisp internals, but 
a byte-coded implementation is somewhat similar to special hardware, in some
ways, in that you'll never compile out the byte codes, and so you probably
always get safety.

Compile-to-native-code is the default for most other implementations, so I'd
bet you're likely to see a much bigger effect.

In general, I think tuning your code for clisp is a different business
altogether than tuning for any other implementation... But regardless of the
specifics of which things will and won't be optimized, the fact is that 
there is no substitute for vendor documentation when doing tuning.  This is
simply not a language issue except insofar as what you've already noticed,
which is that the language lets you specify very general preferences
"just in case". In most situations, you'll have to do more than that.

Sometimes you'll need different declarations in different implementations
to get the same effect, exactly because it's up to the implementation how
to interpret things.  For example, some implementations look for a specific
threshold value ("Is SAFETY bigger than 2?  Good, then do this 
optimization.") while others look for comparative values ("Is SPEED bigger
than SPACE?" Good, then do this optimization.")  And some use both 
techniques, but depending on the circumstance.
From: Dennis Dunn
Subject: Re: Simple question about optimize
Date: 
Message-ID: <1XqCa.93716$BA.31046671@twister.columbus.rr.com>
Hello,

> [presumably with one extra close paren]

Yes, Outlook apparently doesn't know how to blink the matching paren and I
can't find the setting anywhere. :)

Thanks for your input on what the CLHS is actually telling me. I will take a
closer look at the vendors documentation.

--dennis
From: Thomas A. Russ
Subject: Re: Simple question about optimize
Date: 
Message-ID: <ymid6hwmnxe.fsf@sevak.isi.edu>
It really does depend on your code.  Unless you make use of certain
forms (like arrays or structs) which can omit safety checks, or else
write numeric code with appropriate type declarations, there may not be
very much that the compiler can do to optimize the code.

But to go back to a more fundamental level:  Why are you trying to
optimize the code via the compiler?  Is it running too slowly?  Would an
algorithm change be better than squeezing extra performance out of your
current algorithm?


-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Dennis Dunn
Subject: Re: Simple question about optimize
Date: 
Message-ID: <i7TCa.95601$BA.32321928@twister.columbus.rr.com>
Hello,

> But to go back to a more fundamental level:  Why are you trying to
> optimize the code via the compiler?  Is it running too slowly?  Would an

As a learning exercise I wrote a little Lisp program to make a picture of
the Mandelbrot set.  Given a region bounded by two points (upper-left,
lower-right) write a bitmap image of that region of the set.  While I was
browsing the internet for information on algorithms I found this site that
told me more about the subject than I ever thought was possible.
Apparently, one of the things that mathematicians do is to calculate the
area of the set.  I thought that would be an interesting problem.

My program estimates the area by throwing darts at a picture of the region
bounding the set and then calculating the percentage of those darts that
landed in the set.  If n% of them landed in the set then n% of the region is
in the set, ie the area.  Because the points I test are randomly selected
the area is then a random variable.  If I repeat the experiment a bunch of
times the expected value of the random variable 'area  should approach the
actual area of the Mandlebrot set.

> algorithm change be better than squeezing extra performance out of your
> current algorithm?

Probably.  I make extensive use of the complex datatype so maybe a simple
type declaration in the appropriate forms would be all I need.  It was
taking about 10 seconds to do one run, with

#+lispworks(eval-when (:compile-toplevel) (proclaim '(optimize (speed 3)
(safety 0))))

at the top of the file the execution time dropped to 1 second when executing
the program under Lispworks.

I'll go back and see what the type declaration does for me.  I like that
idea better than the shotgun approach of the proclaim form because it's more
specific.  Let the learning continue!!

Thanks for your comments.

--dennis
From: nevada
Subject: Re: Simple question about optimize
Date: 
Message-ID: <5e954cc3.0306030539.51108b56@posting.google.com>
Where is this site?

NS

> While I was
> browsing the internet for information on algorithms I found this site that
> told me more about the subject than I ever thought was possible.
From: Dennis Dunn
Subject: Re: Simple question about optimize
Date: 
Message-ID: <lObDa.97111$BA.33169575@twister.columbus.rr.com>
Share and Enjoy!

http://www.mrob.com/pub/muency.html

"nevada" <············@yahoo.com> wrote in message
·································@posting.google.com...
> Where is this site?
>
> NS
>
> > While I was
> > browsing the internet for information on algorithms I found this site
that
> > told me more about the subject than I ever thought was possible.
From: Thomas A. Russ
Subject: Re: Simple question about optimize
Date: 
Message-ID: <ymi7k83m66a.fsf@sevak.isi.edu>
"Dennis Dunn" <·····@insight.rr.com> writes:

> 
> #+lispworks(eval-when (:compile-toplevel) (proclaim '(optimize (speed 3)
> (safety 0))))
> 
> at the top of the file the execution time dropped to 1 second when executing
> the program under Lispworks.
> 
> I'll go back and see what the type declaration does for me.  I like that
> idea better than the shotgun approach of the proclaim form because it's more
> specific.  Let the learning continue!!

Well, you will actually need both of those together.  Typically, unless
you ask the compiler to optimize, the default is usually not to do
anything special with the information provided by the type declarations.

If you don't want to have global optimization, then you can turn it on
in particular functions by just adding the optimize declaration inside
the function:

(defun do-fast (n)
  (declare (fixnum n)
           (optimize (speed 3) (safety 0) (debug 0))
	)
  (dotimes (i 10000000)
    (setq n (+ n 1)))
  n)

To see a difference, compare it with

(defun do-slow (n)
  (declare (fixnum n)
           (optimize (speed 0) (safety 3) (debug 3))
	)
  (dotimes (i 10000000)
    (setq n (+ n 1)))
  n)


-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Dennis Dunn
Subject: Re: Simple question about optimize
Date: 
Message-ID: <1zdDa.97133$BA.33290444@twister.columbus.rr.com>
Hello,

Thanks for your comments.  I'll try to optimize the one form that is doing
all the work and see how that compares to using the global (proclaim) form.

--dennis