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