Numerical code efficiency

"Dan Muller" <[email protected]> Sun, 12 Oct 2003 11:17:21 -0400
Newsgroups gmane.lisp.corman
Message-ID <[email protected]>
I've been reacquainting myself with Lisp for the last few weeks, having not 
used it for about twenty years. I'm doing it partly for fun and general 
edification, but I'm also evaluating its suitability for the sort of number 
crunching one might find in a Newtonian physics simulator. I've been using 
Corman Lisp 2.5 for my investigations.

I just did a few investigations into performance for a very simple function 
to sum floating point numbers. I'd like to find out if my approach to 
optimizing a little subroutine like this is appropriate, and if my results 
are typical for Lisps in general.

Here's the entire test file:
(declaim
      (optimize
         (speed 3)
         (compilation-speed 0)
         (safety 0)
         (debug 0)))

(defun sum-reduce (v)
     (reduce #'+ v))

(defun sum-reduce-df (v)
     (declare (type (vector double-float 10) v))
     (the double-float (reduce #'+ v)))

(defun sum-loop (v)
     (let ((acc (svref v 0))
           (len (length v)))
         (do ((i 1 (1+ i)))
             ((eq i len) acc)
             (setq acc (+ acc (svref v i))))))

(defun sum-loop-df (v)
     (declare (type (vector double-float 10) v))
     (let ((acc (svref v 0))
           (len (length v)))
         (declare (type double-float acc))
         (do ((i 1 (1+ i)))
             ((eq i len) acc)
             (declare (type fixnum i))
             (setq acc (+ acc (svref v i))))))

(defun test-sum (label f)
     (format t "~&~A:~%" label)
     (let ((v #(1.0d0 2.0d0 3.0d0 4.0d0 5.0d0 6.0d0 7.0d0 8.0d0 9.0d0 10.0d0)))
         (gc)
         (time
             (dotimes (i 1000000)
                 (declare (type fixnum i))
                 (funcall f v))))
     (values))

(test-sum "Lambda reduce-plus" #'(lambda (x) (reduce #'+ x)))
(test-sum "SUM-REDUCE"    #'sum-reduce)
(test-sum "SUM-REDUCE-DF" #'sum-reduce-df)
(test-sum "SUM-LOOP"      #'sum-loop)
(test-sum "SUM-LOOP-DF"   #'sum-loop-df)
:DONE


And here's some typical output from executing this file:

T
SUM-REDUCE
SUM-REDUCE-DF
SUM-LOOP
SUM-LOOP-DF
TEST-SUM
Lambda reduce-plus:
Total Execution time: 6.169552 seconds
Time spent garbage collecting: 0.416621 seconds
SUM-REDUCE:
Total Execution time: 6.105878 seconds
Time spent garbage collecting: 0.400325 seconds
SUM-REDUCE-DF:
Total Execution time: 6.104992 seconds
Time spent garbage collecting: 0.441325 seconds
SUM-LOOP:
Total Execution time: 2.698069 seconds
Time spent garbage collecting: 0.31516 seconds
SUM-LOOP-DF:
Total Execution time: 2.706086 seconds
Time spent garbage collecting: 0.317234 seconds
:DONE



The lambda form, sum-reduce, and sum-reduce-df all consistently execute in 
about the same time. The fact that a hand-coded loop is faster didn't 
surprise me much, based on what I'd read in Paul Graham's ANSI Common Lisp. 
But two things did surprise me:

1. Adding type declarations didn't seem to improve matters. Am I using them 
appropriately? I tried single-float instead of double-float, but there was 
no discernible difference. Also, the declamation of i in the loop made no 
difference.

2. Looking at the disassembled functions, i noticed that svref results in 
an actual function call, as does the call to #'+. Is there any way around 
this? Declaiming these inline doesn't work; I get a warning that the source 
isn't accessible.

Assuming I'm not doing anything wrong: Is this typical for Lisps in 
general? The generated code makes me suspect that writing low-level matrix 
and vector manipulation functions in Lisp would lead to mediocre results 
for a production-quality program. That's not necessarily a big problem; 
it's certainly the sort of thing that one might expect to hand-optimize 
using assembler or by calling a third-party library. I'm just curious about 
how far straight Lisp programming can be stretched for math-intensive 
programming. Although using multiple languages is common, it's certainly 
nicer when you don't have to mess with crossing the boundaries.

Thanks in advance for your comments.



Dan Muller
[email protected]

Some people believe in absolutes. Others aren't so sure.



---
avast! Antivirus: Outbound message clean.
Virus Database (VPS): 10/9/2003
Tested on: 10/12/2003 11:17:23 AM
avast! is copyright (c) 2000-2003 ALWIL Software.
http://www.avast.com




------------------------ Yahoo! Groups Sponsor ---------------------~-->
Buy Ink Cartridges or Refill Kits for your HP, Epson, Canon or Lexmark
Printer at MyInks.com. Free s/h on orders $50 or more to the US & Canada.
http://www.c1tracking.com/l.asp?cid=5511
http://us.click.yahoo.com/mOAaAA/3exGAA/qnsNAA/SyjtlB/TM
---------------------------------------------------------------------~->

To unsubscribe from this group, send an email to:
[email protected]

 

Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/