Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.1 6/24/83; site clan.UUCP
Path: utzoo!dciem!nrcaero!clan!holtz
From: holtz@clan.UUCP (Neal Holtz)
Newsgroups: net.ai
Subject: Re: Thus spake the DoD ... (really - Lisp performance, etc.)
Message-ID: <153@clan.UUCP>
Date: Wed, 6-Mar-85 09:16:08 EST
Article-I.D.: clan.153
Posted: Wed Mar  6 09:16:08 1985
Date-Received: Thu, 7-Mar-85 06:50:56 EST
Distribution: net.lang.lisp,net.lang.ada
Organization: Systems Eng., Carleton Univ., Ottawa, Canada
Lines: 122

Daniel Salomon raised the old issue of (supposed) Lisp inefficiency;
this has been answered well, many times, but ...

Following are some results of a quick comparison using the standard,
stupid recursive Fibonacci calculation, in 4 popular languages (yes,
even Fortran!).  I know that this is not terribly relevant, but still
the results are interesting, and some might find them surprising.
They are presented at the end, so you don't have to read them (Lisp
wins, by the way -- Mr. Shebs is right, Portable Standard Lisp really
flies).

More importantly, I have recently been toying with a slightly more realistic
application -- critical path computations for project planning.  I quickly
wrote a very nice, though minimal, implemention in PSL of the
"activity-on-node" model.  Took 3 or 4 hours, occupies about 4 pages
of listing, does a lot of error and consistency checking, allows nice
(and minimal) input (i.e., for each activity you simply give its duration
and list of predecessors), and is very understandable (I think).  It also
uses natural and easily extensible data structures, so it is very clear
how to extend this for more realistic modelling.  For a 1000 activity network,
with an average of about 6 predecessors for each activity, on an 11/750,
it takes 40 CPU seconds to read in the data and construct
the network, and 90 seconds to compute early-start and late-finish time
for each activity (using extremely simple recursive algorithms 6 lines long).

I would be surprised if an equivalent C or Fortran program was significantly 
faster.  Even if they were, that would be largely irrelevant.  A 1000 
activity network is LARGE.  90 seconds of elapsed time on a personal
workstation is very easy to accept.  It is unlikely that a tripling of speed
would ever pay for the increased implementation cost (particulary the
Fortran implementation cost).

---------

CPU time (in sec.) for avg. of 5 runs of fib(25) [= 121393]
(Optimizers turned on where possible)

          Apollo DN320      Vax 11/750
                 Aegis         4.2 BSD

Fortran -        11.39               ?
C       -        10.05            8.78   (cc -O)
Pascal  -         8.09           10.88   (pc -O)
PS Lisp -         5.38            5.80


The uninteresting code follows:


% ************************* Portable Standard Lisp *************************

(BothTimes (load fast-arith fast-int))

(de fib (n)
   (if (or (= n 0) (= n 1))
       1
       (+ (fib (- n 1)) (fib (- n 2)))
       ))

(de run ()
   (let ((res (fib 25)))
        (printf "Result is %w%n" res)
        ))

/* ************************* C ************************* */

long fib( n )
long n;
{
    if( n == 0 || n == 1 )
        return( 1 );
    else
        return( fib(n-1) + fib(n-2) );
}

main()
{
   long res;

   res = fib( 25 );
   printf( "Result is %ld\n", res );
}


{ ************************* Pascal ************************* }

program fibi(output);
 
type integer32 = integer;   { delete this line for Apollo }

var result : integer32;

function fib( n : integer32 ) : integer32;
begin
   if (n = 0) or (n = 1) then
      fib := 1
   else
      fib := fib( n-1 )  +  fib( n-2 );
end;

begin
   result := fib( 25 );
   writeln( 'Result is ', result );
end.

 
C ************************* Fortran *************************

      integer*4 res
      integer*4 fib
      res = fib( 25 )
      write(*,*) 'Result is ',res
      end
      integer*4 function fib( n )
      integer*4 n
      if( (n .eq. 0) .or. (n .eq. 1) ) then
         fib = 1
      else
         fib = fib( n-1 ) + fib( n-2 )
      endif
      end