From - Wed Apr 5 21:00:07 2000
Return-Path:
Received: (from randy@localhost)
by euclid.acs.nmu.edu (8.9.3/8.9.3) id XAA03660;
Tue, 21 Mar 2000 23:48:40 -0500
Date: Tue, 21 Mar 2000 23:48:40 -0500
From: Randy Appleton
Message-Id: <200003220448.XAA03660@euclid.acs.nmu.edu>
To: randy@euclid.acs.nmu.edu
Subject: Fwd: C speed vs functional languages
Reply-To: randy@euclid.acs.NMU.EDU (Randy Appleton)
Path: walter.acs.nmu.edu!newsxfer3.itd.umich.edu!logbridge.uoregon.edu!ihug.co.nz!brucehoult
From: brucehoult@pobox.com (Bruce Hoult)
Newsgroups: comp.arch
Subject: C speed vs functional languages
Date: Mon, 20 Mar 2000 17:49:46 +1200
Organization: The Internet Group Ltd
Lines: 86
Message-ID:
NNTP-Posting-Host: p17-max4.wlg.ihug.co.nz
X-Newsreader: MT-NewsWatcher 2.4.4
Xref: walter.acs.nmu.edu comp.arch:10646
In article , David Gay
wrote:
> brucehoult@pobox.com (Bruce Hoult) writes:
> > The conceptual work neded to make compiled scheme go as fast as C was done
> > by ... oh ... 1976 or so [1].
> >
> > These days, Scheme compilers such as Stalin [2] produce awesome code. In
> > fact Stalin often produces faster code than hand-written C despite the
> > fact that it generates C, because you would never ever have the patience
> > and skill to do all the bookkeeping required to do it by hand.
>
> I've heard these kinds of claim rather too often to believe them without
> substantial proof. References ? (I looked through the Stalin release
> and the author's web site, but didn't find anything)
OK, I've found a concrete (and impressive) claim...
In the articles...
... Siskind claims a 21:1 speed advantage for Stalin-compiled Scheme vs C,
on a 2D numerical integration code.
Here is the Scheme code:
(define (integrate-1D L U F)
(let ((D (/ (- U L) 8.0)))
(* (+ (* (F L) 0.5)
(F (+ L D))
(F (+ L (* 2.0 D)))
(F (+ L (* 3.0 D)))
(F (+ L (* 4.0 D)))
(F (- U (* 3.0 D)))
(F (- U (* 2.0 D)))
(F (- U D))
(* (F U) 0.5))
D)))
(define (integrate-2D L1 U1 L2 U2 F)
(integrate-1D L2 U2 (lambda (y) (integrate-1D L1 U1 (lambda (x) (F x y))) )))
(define (zark U V)
(integrate-2d 0.0 U 0.0 V (lambda (X Y) (* X Y)) ))
(define (r-total N)
(do ((I 1 (+ I 1))
(Sum 0.0 (+ Sum (zark (* I 1.0) (* I 2.0)))))
((> I N) Sum)))
(define (i-total N)
(do ((I 1 (+ I 1))
(Sum 0.0 (+ Sum (let ((I2 (* (* I I) 1.0))) (* I2 I2)))))
((> I N) Sum)))
(define (error-sum-of-squares N)
(do ((I 1 (+ I 1))
(Sum 0.0 (+ Sum (let ((E (- (r-total I) (i-total I)))) (* E E)))))
((> I N) Sum)))
(begin (display (error-sum-of-squares 1000)) (newline))
Siskind does admit to a slight cheat in this two year old message -- he
hand-expanded the 35 line scheme program into a 342 line version, claiming
that Stalin would soon make this transformation automatically.
Given that it's now two years later, I just tried the Scheme code (35
lines) and the C code (58 lines) from the second deja message referenced
above. Using what appears to be the standard set of flags (those in
benchmarks/compile-stalin-benchmark) I got the following runtimes on my
200 MHz Pentium Pro, 256 KB cache, RedHat Linux 5.2 (1.0.36),
egcs-2.91.66:
C : 27.90 sec
Scheme: 5.85 sec
I don't know if some other set of flags would get the Scheme program down
to the claimed 1 second runtime -- I just use the standard set of flags
all the time. Beating the C code by a factor of nearly 5 is still pretty
good.
-- Bruce