From: Dave Fayram
Subject: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <38ff3d6c.0406151602.212bffae@posting.google.com>
I must admit, I'm not much of one for speed benchmarks. They're
simple, don't demonstrate much, and they're kind of silly. But when I
see how much publicity was just won over at Slashdot for
http://www.sys-con.com/story/?storyid=45250 it makes me think...

I think we, as a group, should set up a comparison of Lisp performance
vs. Java Performance vs. the reference C++ performance. I suspect that
if we use a commercial lisp compiler like ACL or LispWorks, we'll see
comparable results, and if we do, then we've got a time window right
now where we can make a lot of positive press.

This isn't just a PR move. It's fun to aim a kick at the Java
community every now and then. :) If it turns out the JVMs are faster,
then our Lisp Compiler vendors have valuable feedback. If they're
faster, then we generate lots of positive press for lisp. Sounds like
a win-win scenario to me.

I'll cheerfully host such a page and work to get it on a sever that
could handle a slashdotting, but I lack fast x86 machines to work with
(since Java and G++ are both much better at working with x86 machines
compared to all my PPC machines). Is anyone interested?

From: Ari Johnson
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <ieOzc.9$5t2.6@fed1read01>
Dave Fayram wrote:
> I'll cheerfully host such a page and work to get it on a sever that
> could handle a slashdotting, but I lack fast x86 machines to work with
> (since Java and G++ are both much better at working with x86 machines
> compared to all my PPC machines). Is anyone interested?

Actually, in my experience, without JIT, Java is much faster on a Sparc 
box.  Java must be big-endian. :)
From: Dmitry Kim
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <20040616042655.7cca21b3@jsn.nichego.net>
	hi,

On 15 Jun 2004 17:02:57 -0700 ·········@lensmen.net (Dave Fayram) wrote:
> I think we, as a group, should set up a comparison of Lisp performance
> vs. Java Performance vs. the reference C++ performance. I suspect that
> if we use a commercial lisp compiler like ACL or LispWorks, we'll see
> comparable results, and if we do, then we've got a time window right
> now where we can make a lot of positive press.

did you see "The Great Computer Language Shootout"? the project was
revived recently at http://shootout.alioth.debian.org.
they don't do no closed-source language implementation, but cmucl and
emacs lisp are on the list, as well as several scheme implementations.

the funny part is http://shootout.alioth.debian.org/craps.php, a
scorecard for configurable language comparision. cmucl and bigloo scheme
are numbers 6 and 7 in speed contest (while java is java and perl are
#13 and #14). cmucl and bigloo are also #3 and #5 in speed +
lines-of-source contest (perl is #8 and java is #9).

-jsn.

RIPE nic-handle: JSN7-RIPE, email address: jason [AT] nichego [.] net
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <cao937$8lh$1@ulric.tng.de>
Dmitry Kim schrieb:

> did you see "The Great Computer Language Shootout"? the project was
> revived recently at http://shootout.alioth.debian.org.
> they don't do no closed-source language implementation, but cmucl and
> emacs lisp are on the list, as well as several scheme implementations.

I would be interested to hear the opinion of some experienced Lispnicks 
about what they think about the code which is used for the Lisp examples.

For example look at http://shootout.alioth.debian.org/bench/hash/hash.cmucl


21 LOC.

While the Python version is only 13 LOC and 4 can be take away, so we get:
# Begin
import sys

n = int(sys.argv[1])
X = {}
myhex = hex
for i in xrange(1,n+1): X[myhex(i)[2:]] = i
c = 0
has_key = X.has_key
for i in xrange(n, 0, -1): c += has_key(`i`)
print c
# End

Its a difference. Can the cmucl solution be optimized?
Can other programs be optimized regarding execution speed, LOC and 
memory usage? This way we could do a bit of what the OP suggested...


Andr�
--
From: PKY
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <9eb48ce9.0406160054.53a10014@posting.google.com>
Andr� Thieme <······························@justmail.de> wrote in message news:<············@ulric.tng.de>...
> Dmitry Kim schrieb:
> 
> > did you see "The Great Computer Language Shootout"? the project was
> > revived recently at http://shootout.alioth.debian.org.
> > they don't do no closed-source language implementation, but cmucl and
> > emacs lisp are on the list, as well as several scheme implementations.
> 
> I would be interested to hear the opinion of some experienced Lispnicks 
> about what they think about the code which is used for the Lisp examples.
> 
> For example look at http://shootout.alioth.debian.org/bench/hash/hash.cmucl
> 
> 
> 21 LOC.
> 
> While the Python version is only 13 LOC and 4 can be take away, so we get:
> # Begin
> import sys
> 
> n = int(sys.argv[1])
> X = {}
> myhex = hex
> for i in xrange(1,n+1): X[myhex(i)[2:]] = i
> c = 0
> has_key = X.has_key
> for i in xrange(n, 0, -1): c += has_key(`i`)

> print c
> # End
> 
> Its a difference. Can the cmucl solution be optimized?
> Can other programs be optimized regarding execution speed, LOC and 
> memory usage? This way we could do a bit of what the OP suggested...
> 
> 
> Andr�
> --


file reverse should push the segment into list and call
(mapcar #'write-string-in-reverse (nreverse list-of-segments))

so the unnecessary memory copies would be eliminated.


 PKY
From: Kenny Tilton
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <ATPzc.188522$WA4.83210@twister.nyc.rr.com>
Andr� Thieme wrote:
> Dmitry Kim schrieb:
> 
>> did you see "The Great Computer Language Shootout"? the project was
>> revived recently at http://shootout.alioth.debian.org.
>> they don't do no closed-source language implementation, but cmucl and
>> emacs lisp are on the list, as well as several scheme implementations.
> 
> 
> I would be interested to hear the opinion of some experienced Lispnicks 
> about what they think about the code which is used for the Lisp examples.
> 
> For example look at http://shootout.alioth.debian.org/bench/hash/hash.cmucl
> 
> 
> 21 LOC.
> 
> While the Python version is only 13 LOC and 4 can be take away, so we get:
> # Begin
> import sys
> 
> n = int(sys.argv[1])
> X = {}
> myhex = hex
> for i in xrange(1,n+1): X[myhex(i)[2:]] = i
> c = 0
> has_key = X.has_key
> for i in xrange(n, 0, -1): c += has_key(`i`)
> print c
> # End
> 
> Its a difference.

I was thinking it's a bullshit difference. Length matters? I should look 
into some the spam i have been blocking.

I mean, you /like/ that code? You must be (,:}{`)(# joking.

kenny

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <caojbd$ec2$1@ulric.tng.de>
Kenny Tilton schrieb:

> I was thinking it's a bullshit difference. Length matters?

Yes, it does.
At least so many people argue when they compare for example Lisp to C++ 
code. So why should it not matter if something beats Lisp in some 
situations?


> I mean, you /like/ that code? You must be (,:}{`)(# joking.

I don't like it but I also don't dislike it. It is not my code, I did 
not work with it and in fact I only looked a few seconds on it. Until 
now I have no personal relationship to it.
 From a short view I see no problems with it. A scripting language is 
used to do a scripting task.
Kenny, it is not a program used to control workflows in an atomic power 
plant. Also the author states that this shootout does not explain much 
about the quality of language X. However, many people are impressed by 
it, so I asked if some gurus can join the party and see if something can 
be optimized.


Andr�
--
From: Dmitry Kim
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <20040616065646.51faf324@jsn.nichego.net>
	hi,

On Wed, 16 Jun 2004 03:54:09 +0200 Andr_ Thieme  
<······························@justmail.de> wrote:
> While the Python version is only 13 LOC and 4 can be take away, so we
> get:# Begin
> import sys
> 
> n = int(sys.argv[1])
> X = {}
> myhex = hex
> for i in xrange(1,n+1): X[myhex(i)[2:]] = i
> c = 0
> has_key = X.has_key
> for i in xrange(n, 0, -1): c += has_key(`i`)
> print c
> # End
> 
> Its a difference. Can the cmucl solution be optimized?
> Can other programs be optimized regarding execution speed, LOC and 
> memory usage? This way we could do a bit of what the OP suggested...

i think these questions are addressed in "Testing Methodology" section
of project docs. your lines-of-code optimizations for python probably
contradict this document "the same way" principle (like, probably, this
test *must* have a "main" wrapper function). they also probably
contradict the project code formatting rules (doesn't one-line `for'
statement hurt the readability?).

imho, "Latency vs. Throughput Tests" is an interesting issue. on my box
'guile -e quit' takes 200+ ms -- thus, when the whole test case run
takes 300 ms, what we measure is mostly startup time. afair, both cmucl
and java [bytecode interpreter] startup times are quite noticeable too.

-jsn.

RIPE nic-handle: JSN7-RIPE, email address: jason [AT] nichego [.] net
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <caoitt$e0f$1@ulric.tng.de>
Dmitry Kim schrieb:

> i think these questions are addressed in "Testing Methodology" section
> of project docs. your lines-of-code optimizations for python probably
> contradict this document "the same way" principle (like, probably, this
> test *must* have a "main" wrapper function). they also probably
> contradict the project code formatting rules (doesn't one-line `for'
> statement hurt the readability?).

Well, one-line for's are not typical.. anyways, in a scripting language 
and 11 lines of code it does not really hurt.

But why doesn't the Pythoniast in this example define his own quicksort?
http://shootout.alioth.debian.org/bench/moments/moments.python

(if we forget the "prints" the full code is easily on one screen)


Bulent Murtezaoglu made one for the lisp version:
http://shootout.alioth.debian.org/bench/moments/moments.cmucl

This one is around 3 screens of code.
The lisp version is four times faster.


> imho, "Latency vs. Throughput Tests" is an interesting issue. on my box
> 'guile -e quit' takes 200+ ms -- thus, when the whole test case run
> takes 300 ms, what we measure is mostly startup time. afair, both cmucl
> and java [bytecode interpreter] startup times are quite noticeable too.

Yes.. this startup time really is noticeable.


Andr�
--
From: Rob Warnock
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <dPydnT3of_RXYlLd4p2dnA@speakeasy.net>
Andr� Thieme  <······························@justmail.de> wrote:
+---------------
| Dmitry Kim schrieb:
| > imho, "Latency vs. Throughput Tests" is an interesting issue. on my box
| > 'guile -e quit' takes 200+ ms -- thus, when the whole test case run
| > takes 300 ms, what we measure is mostly startup time. afair, both cmucl
| > and java [bytecode interpreter] startup times are quite noticeable too.
| 
| Yes.. this startup time really is noticeable.
+---------------

Must be a slow machine. On my laptop[1], "guile -e quit" takes ~30ms,
and "cmucl -noinit -eval '(quit)'" takes ~14ms. [The "-noinit" is 'cuz
my default init file's kinda long.]


-Rob

[1] H-P ze4650 with AMD Mobile Athlon XP2500+ (1.855 GHz), running
    CMUCL-18e (FreeBSD native binaries) under FreeBSD 4.9.

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Dmitry Kim
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <20040616125957.5e5adcfe@jsn.nichego.net>
	hi,

On Wed, 16 Jun 2004 03:07:38 -0500 ····@rpw3.org (Rob Warnock) wrote:
> | Yes.. this startup time really is noticeable.
> +---------------
> 
> Must be a slow machine. On my laptop[1], "guile -e quit" takes ~30ms,
> and "cmucl -noinit -eval '(quit)'" takes ~14ms. [The "-noinit" is 'cuz
> my default init file's kinda long.]

yes, my notebook is (an order of magnitude) slower -- it's P2/366MHz.
if the Shoutout tests are run on 1.1GHz Athlon (as the docs say), cmucl
startup time will be probably something like 14ms * (1.855GHz / 1.1GHz)
= 23.6ms. now,"hello, world" test case runs cmucl 200 times, it's 23.6ms
* 200 = 4.7 seconds. and that's why cmucl is #23 on this test.

-jsn.

RIPE nic-handle: JSN7-RIPE, email address: jason [AT] nichego [.] net
From: Julian Stecklina
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <863c4uk1bv.fsf@web.de>
····@rpw3.org (Rob Warnock) writes:

> Andr� Thieme  <······························@justmail.de> wrote:
> +---------------
> | Dmitry Kim schrieb:
> | > imho, "Latency vs. Throughput Tests" is an interesting issue. on my box
> | > 'guile -e quit' takes 200+ ms -- thus, when the whole test case run
> | > takes 300 ms, what we measure is mostly startup time. afair, both cmucl
> | > and java [bytecode interpreter] startup times are quite noticeable too.
> | 
> | Yes.. this startup time really is noticeable.
> +---------------
>
> Must be a slow machine. On my laptop[1], "guile -e quit" takes ~30ms,
> and "cmucl -noinit -eval '(quit)'" takes ~14ms. [The "-noinit" is 'cuz
> my default init file's kinda long.]
>
>
> -Rob
>
> [1] H-P ze4650 with AMD Mobile Athlon XP2500+ (1.855 GHz), running
>     CMUCL-18e (FreeBSD native binaries) under FreeBSD 4.9.

My XP 2400+ (exactly 2 GHz) needs about 7ms, when CMU CL is already
cached. I never knew how fast its startup really is. 


Regards,
-- 
Julian Stecklina 

Signed and encrypted mail welcome.
Key-Server: pgp.mit.edu         Key-ID: 0xD65B2AB5
FA38 DCD3 00EC 97B8 6DD8  D7CC 35D8 8D0E D65B 2AB5

Any sufficiently complicated C or Fortran program
contains an ad hoc informally-specified bug-ridden
slow implementation of half of Common Lisp.
 - Greenspun's Tenth Rule of Programming
From: Dmitry Kim
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <20040616131304.48efa3f5@jsn.nichego.net>
	hi,

On Wed, 16 Jun 2004 06:42:00 +0200 Andr_ Thieme  
<······························@justmail.de> wrote:
> But why doesn't the Pythoniast in this example define his own
> quicksort?
> http://shootout.alioth.debian.org/bench/moments/moments.python
> 
> (if we forget the "prints" the full code is easily on one screen)
> 
> Bulent Murtezaoglu made one for the lisp version:
> http://shootout.alioth.debian.org/bench/moments/moments.cmucl

i didn't really read the code samples, but if it is the real quicksort,
python language probably has its quicksort implemented in C. rewriting
it in python will probably hurt performance.

-jsn.

RIPE nic-handle: JSN7-RIPE, email address: jason [AT] nichego [.] net
From: Nicolas Neuss
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <87isdsj5ak.fsf@ortler.iwr.uni-heidelberg.de>
Andr� Thieme <······························@justmail.de> writes:

> I would be interested to hear the opinion of some experienced Lispnicks
> about what they think about the code which is used for the Lisp examples.
> 
> For example look at http://shootout.alioth.debian.org/bench/hash/hash.cmucl
> ...
> Its a difference. Can the cmucl solution be optimized?
> Can other programs be optimized regarding execution speed, LOC and memory
> usage? This way we could do a bit of what the OP suggested...
> 
> 
> Andr�

The problem with this test is the following: it forces all languages to
communicate with the Unix shell.  Why this is fine for Unix scripting
languages (and even C/C++), it doubles the size of each of the (toy)
programs for languages like Lisp/Scheme which bring their own (much
stronger) environments with them.

I'm sorry, but I cannot take this test seriously.  The world does not
consist of Fibonacci functions communicating with Unix shells.

Nicolas.
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <caqudf$2gh$1@ulric.tng.de>
Nicolas Neuss schrieb:

> Andr� Thieme <······························@justmail.de> writes:
> 
> 
>>I would be interested to hear the opinion of some experienced Lispnicks
>>about what they think about the code which is used for the Lisp examples.
>>
>>For example look at http://shootout.alioth.debian.org/bench/hash/hash.cmucl
>>...
>>Its a difference. Can the cmucl solution be optimized?
>>Can other programs be optimized regarding execution speed, LOC and memory
>>usage? This way we could do a bit of what the OP suggested...
>>
> 
> The problem with this test is the following: it forces all languages to
> communicate with the Unix shell.  Why this is fine for Unix scripting
> languages (and even C/C++), it doubles the size of each of the (toy)
> programs for languages like Lisp/Scheme which bring their own (much
> stronger) environments with them.
> 
> I'm sorry, but I cannot take this test seriously.  The world does not
> consist of Fibonacci functions communicating with Unix shells.

I agree with you here. However, many people take these "benchmarks" very 
serious and don't pay much attention to the conclusions made by the 
author (that the tests have no meaning for the real world).

They see that ocaml has nearly C speed and often has the shortest 
examples. By applying "logic" to this situation they know that ocaml is 
the best programming language.


Andr�
--
From: Dmitry Kim
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <20040617063249.2a732825@jsn.nichego.net>
	hi,

On Thu, 17 Jun 2004 04:10:19 +0200 Andr_ Thieme  
<······························@justmail.de> wrote:
> I agree with you here. However, many people take these "benchmarks"
> very serious and don't pay much attention to the conclusions made by
> the author (that the tests have no meaning for the real world).
> 
> They see that ocaml has nearly C speed and often has the shortest 
> examples. By applying "logic" to this situation they know that ocaml
> is the best programming language.

yeah, right. that's the point, exactly. that's what Dave Fayram was
talking about in his post, if i heard that correct. we can waste
all our lives away crying "the benchmark is broken" and "tests have no
meaning for the real world"-- and they probably *are* broken and all --
but the problem is, many people take these "benchmarks" *very*
seriously. and these people are mostly potential lisp users.

yes, it's just that simple: benchmarks sell. the language can be sweet
as i-don't-know-what, but it looses the popular benchmark, and ooops --
it's toast.
and now a little quiz:
1) how many people will be converted to ocaml after the shootout?
2) how many people will be converted to lisp after the shootout?
3) which number is greater and why?

-jsn.

RIPE nic-handle: JSN7-RIPE, email address: jason [AT] nichego [.] net
From: Alain Picard
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <87k6y6y21c.fsf@memetrics.com>
Dmitry Kim <·····@redline.ru> writes:

> yeah, right. that's the point, exactly. that's what Dave Fayram was
> talking about in his post, if i heard that correct. we can waste
> all our lives away crying "the benchmark is broken" and "tests have no
> meaning for the real world"-- and they probably *are* broken and all --
> but the problem is, many people take these "benchmarks" *very*
> seriously. and these people are mostly potential lisp users.

I just don't buy this at all.  In "Real Life", the decision to 
use not only a language, but an _implementation_ of a language,
is a serious matter to most engineers and project managers.  And
"benchmarks" showing the speed of a "language" (not that there is
such a thing) are far, far, far down the list of things to consider.
So far, in fact, that they are never even looked at.  It boils down to:

 * what do your engineers know
 * what is trendy (how many contractors can you hire in a hurry)
 * what library support is there for your application domain
 * how much does the development environment cost
 * how much does the deployment/runtime cost

If you're really really lucky, another point can show up:
 * what do your engineers _recommend_ for technical reasons
   not listed above

If you're in that happy situation (as I was, lucky me) you can
recommend Common Lisp (if you can explain why it's a good choice).
You have to be able to show you can hire programmers, and you have
to be able to show you can get libraries (or that you don't need them).

I wouldn't lose any sleep over the idea that we're losing lispers
due to "benchmarks".

> 1) how many people will be converted to ocaml after the shootout?
Zero.

> 2) how many people will be converted to lisp after the shootout?
Zero.

> 3) which number is greater and why?

Neither, because it's totally irrelevant.
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <cas675$s0c$1@ulric.tng.de>
Alain Picard schrieb:

> I wouldn't lose any sleep over the idea that we're losing lispers
> due to "benchmarks".
> 
> 
>>1) how many people will be converted to ocaml after the shootout?
> 
> Zero.
> 
> 
>>2) how many people will be converted to lisp after the shootout?
> 
> Zero.
> 
> 
>>3) which number is greater and why?
> 
> 
> Neither, because it's totally irrelevant.
> 

We need to see this in a bigger context. I think noone is surfing around 
the web and suddenly finds himself on the benchmark site, reads it and 
is from then on convinced about ocaml.
No, it is a programmer who hears some neat stuff about ocaml and then 
finds a link to the shootout. Of course some camels use the good results 
of the tests as arguments in discussions. So the shootout can add to the 
sympathy to the language. Beeing the only reason to learn it is probably 
really not the case.


Andr�
--
From: Nicolas Neuss
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <87acz2jzjj.fsf@ortler.iwr.uni-heidelberg.de>
Andr� Thieme <······························@justmail.de> writes:

> Nicolas Neuss schrieb:
> ...
> > I'm sorry, but I cannot take this test seriously.  The world does not
> > consist of Fibonacci functions communicating with Unix shells.
> 
> I agree with you here. However, many people take these "benchmarks" very
> serious and don't pay much attention to the conclusions made by the author
> (that the tests have no meaning for the real world).

But why should we dance to this bad music?

One should set up a better test suite where only the function itself is
used for the LOC (yes, one should also omit the main function for C), and
where the optimization is allowed to be declaimed outside the function (as
is the case for C anyway).

----------------------------------------------

Task 1: Fibonacci recursive (compute Fib(35))

CL:

(defun fib (n)
  (declare (fixnum n))
  (the fixnum (if (< n 2) 1 (+ (fib (- n 1)) (fib (- n 2))))))

C:
unsigned long fib(unsigned long n) {
    return( (n < 2) ? 1 : (fib(n-2) + fib(n-1)) );
}

These programs have the same LOC, and also about the same speed.
Perl and Python drop out, of course, due to speed problems.

----------------------------------------------

Task 2: Fibonacci iterative (compute Fib(1000))

CL:

(defun fib (n)
 (loop for a = 1 then b
       and b = 1 then (+ a b)
       repeat n finally (return a)))

C: ?

CL: fast and correct result, C/C++: wrong result or very long program, ...

----------------------------------------------

Task 3: ....

My suggestion is: if you care that much about this stuff you should write
this improved test suite, put it somwhere on the Web and point
C(etc)-people to this page whenever necessary.  If it is well done, it
might even be possible to introduce a link at the Debian shootout page or
www.lisp.org.

Nicolas.

P.S: I mailed Doug Bagley the above points some years ago, but he was not
interested in modifying his test.
From: Bradley J Lucier
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <caslph$8mu@arthur.cs.purdue.edu>
In article <··············@ortler.iwr.uni-heidelberg.de>,
Nicolas Neuss  <·······@iwr.uni-heidelberg.de> wrote:
>
>Task 2: Fibonacci iterative (compute Fib(1000))
>
>CL:
>
>(defun fib (n)
> (loop for a = 1 then b
>       and b = 1 then (+ a b)
>       repeat n finally (return a)))
>
>C: ?
>
>CL: fast and correct result, C/C++: wrong result or very long program, ...

*Really* fast and correct code from Arnold Schoenhage, translated to Scheme
(but fib(1)=fib(2)=1):

(define (fast-fib-pair n)
  ;; returns f_n f_{n+1}
  (case n
      ((1) (values 1 1))
      ((2) (values 1 2))
      (else
       (let ((m (quotient n 2)))
         (call-with-values
             (lambda () (fast-fib-pair m))
           (lambda (f_m f_m+1)
             (let ((f_m^2   (* f_m f_m))
                   (f_m+1^2 (* f_m+1 f_m+1)))
               (if (even? n)
                   (values (- (* 2 f_m+1^2)
                              (* 3 f_m^2)
                              (if (odd? m)
                                  -2
                                  2))
                           (+ f_m^2 f_m+1^2))
                   (values (+ f_m^2 f_m+1^2)
                           (- (* 3 f_m+1^2)
                              (* 2 f_m^2)
                              (if (odd? m)
                              (if (odd? m)
                                  -2
                                  2)))))))))))

Takes .18 seconds to calculate fib(1,000,000) and fib(1,000,001) on a
2GHz G5 PowerMac with Gambit-C 4.0beta4.

(One could also use the usual binary exponential trick on the matrix producct in

[fib(n),fib(n+1)]^T=[[0,1][1,1]]^n [0,1]^T

but this is nowhere near as fast as the code given above.)

Brad
From: Nicolas Neuss
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <87isdpi9ys.fsf@ortler.iwr.uni-heidelberg.de>
···@cs.purdue.edu (Bradley J Lucier) writes:

> *Really* fast and correct code from Arnold Schoenhage, translated to Scheme
> (but fib(1)=fib(2)=1):

So Andre Thieme or whoever wants to write this better test suite could
start with

Task-1-a: recursive Fibonacci for Fib(35)
Task-1-b: iterative Fibonacci for Fib(1000)
Task-1-c: very fast Fibonacci for Fib(1000000)

Implement and time those functions for some languages (for Task-1-a you
can take the versions from the old shootout).

Task-2: ...  (other tests, use tests of the old shootout for inspiration,
look or ask for better ones at c.l.l.)

If those guys really start writing this in a careful way and can show
something looking reasonable, they probably will get a lot of input from
c.l.l.

Nicolas.
From: Nicolas Neuss
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <87acz1i6qz.fsf@ortler.iwr.uni-heidelberg.de>
Some further comments

···@cs.purdue.edu (Bradley J Lucier) writes:

> (but fib(1)=fib(2)=1):

Maybe, but I chose the same numbering as the shootout.

> (define (fast-fib-pair n)
>   ;; returns f_n f_{n+1}
>   (case n
>       ((1) (values 1 1))
>       ((2) (values 1 2))
>       (else
>        (let ((m (quotient n 2)))
>          (call-with-values
>              (lambda () (fast-fib-pair m))
>            (lambda (f_m f_m+1)
>              (let ((f_m^2   (* f_m f_m))
>                    (f_m+1^2 (* f_m+1 f_m+1)))
>                (if (even? n)
>                    (values (- (* 2 f_m+1^2)
>                               (* 3 f_m^2)
>                               (if (odd? m)
>                                   -2
>                                   2))
>                            (+ f_m^2 f_m+1^2))
>                    (values (+ f_m^2 f_m+1^2)
>                            (- (* 3 f_m+1^2)
>                               (* 2 f_m^2)
>                               (if (odd? m)
>                               (if (odd? m)
One should drop one of the last two lines, of course.
>                                   -2
>                                   2)))))))))))
> 
> Takes .18 seconds to calculate fib(1,000,000) and fib(1,000,001) on a
> 2GHz G5 PowerMac with Gambit-C 4.0beta4.

Here is the CL version:

(defun fast-fib-pair (n)
  "Returns f_n f_{n+1}."
  (case n
    ((1) (values 1 1))
    ((2) (values 1 2))
    (t (let ((m (floor n 2)))
         (multiple-value-bind (f_m f_m+1)
             (fast-fib-pair m)
           (let ((f_m^2   (* f_m f_m))
                 (f_m+1^2 (* f_m+1 f_m+1)))
             (if (evenp n)
                 (values (- (* 2 f_m+1^2)
                            (* 3 f_m^2)
                            (if (oddp m) -2 2))
                         (+ f_m^2 f_m+1^2))
                 (values (+ f_m^2 f_m+1^2)
                         (- (* 3 f_m+1^2)
                            (* 2 f_m^2)
                            (if (oddp m) -2 2))))))))))

Of course, this measures mostly bignum multiplication performance.  We know
that CLISP is very good here.  Therefore here the results for a 2.4 GHz
Pentium 4:

[8] (time (progn (fast-fib-pair 1000000) nil))

Real time: 0.257923 sec.
Run time: 0.26 sec.
Space: 1215916 Bytes
GC: 3, GC time: 0.01 sec.
NIL
[9]>

Nicolas.
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <cas5v5$rtv$1@ulric.tng.de>
Nicolas Neuss schrieb:
> Andr� Thieme <······························@justmail.de> writes:
> 
> 
>>Nicolas Neuss schrieb:
>>...
>>
>>>I'm sorry, but I cannot take this test seriously.  The world does not
>>>consist of Fibonacci functions communicating with Unix shells.
>>
>>I agree with you here. However, many people take these "benchmarks" very
>>serious and don't pay much attention to the conclusions made by the author
>>(that the tests have no meaning for the real world).
> 
> 
> But why should we dance to this bad music?
> 
> One should set up a better test suite where only the function itself is
> used for the LOC (yes, one should also omit the main function for C), and
> where the optimization is allowed to be declaimed outside the function (as
> is the case for C anyway).
> 
> ----------------------------------------------
> 
> Task 1: Fibonacci recursive (compute Fib(35))
> 
> CL:
> 
> (defun fib (n)
>   (declare (fixnum n))
>   (the fixnum (if (< n 2) 1 (+ (fib (- n 1)) (fib (- n 2))))))
> 
> C:
> unsigned long fib(unsigned long n) {
>     return( (n < 2) ? 1 : (fib(n-2) + fib(n-1)) );
> }
> 
> These programs have the same LOC, and also about the same speed.
> Perl and Python drop out, of course, due to speed problems.
> 
> ----------------------------------------------
> 
> Task 2: Fibonacci iterative (compute Fib(1000))
> 
> CL:
> 
> (defun fib (n)
>  (loop for a = 1 then b
>        and b = 1 then (+ a b)
>        repeat n finally (return a)))
> 
> C: ?
> 
> CL: fast and correct result, C/C++: wrong result or very long program, ...
> 
> ----------------------------------------------
> 
> Task 3: ....
> 
> My suggestion is: if you care that much about this stuff you should write
> this improved test suite, put it somwhere on the Web and point
> C(etc)-people to this page whenever necessary.  If it is well done, it
> might even be possible to introduce a link at the Debian shootout page or
> www.lisp.org.
> 
> Nicolas.
> 
> P.S: I mailed Doug Bagley the above points some years ago, but he was not
> interested in modifying his test.


I think you gave some nice suggestions and you put some code examples 
into our hands. Now Dave Fayram is at least a little bit closer to his 
Benchmark goal. If he takes the initiative and sets up some tests we 
find here some people who will give more suggestions and contribute code.


Andr�
--
From: Joe Marshall
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <hdtbqv73.fsf@ccs.neu.edu>
Andr� Thieme <······························@justmail.de> writes:

> I would be interested to hear the opinion of some experienced
> Lispnicks about what they think about the code which is used for the
> Lisp examples.
>
> For example look at http://shootout.alioth.debian.org/bench/hash/hash.cmucl

Never mind the Lisp code.  The `benchmarks' are useless and the
methodology sucks.  How often do you need to pipe the result of
Ackermann's function to the shell *really* fast?

Let's see how some of these other languages do on the Boyer benchmark.

;;; Boyer benchmark, Bob Boyer + fixes by Henry Baker

(in-package "CL-USER")

(defun setup ()
  (add-lemma-list
   '((equal (compile form)
	    (reverse (codegen (optimize form)
			      (nil))))
     (equal (eqp x y)
	    (equal (fix x)
		   (fix y)))
     (equal (greaterp x y)
	    (lessp y x))
     (equal (lesseqp x y)
	    (not (lessp y x)))
     (equal (greatereqp x y)
	    (not (lessp x y)))
     (equal (boolean x)
	    (or (equal x (t))
		(equal x (f))))
     (equal (iff x y)
	    (and (implies x y)
		 (implies y x)))
     (equal (even1 x)
	    (if (zerop x)
		(t)
	      (odd (sub1 x))))
     (equal (countps- l pred)
	    (countps-loop l pred (zero)))
     (equal (fact- i)
	    (fact-loop i 1))
     (equal (reverse- x)
	    (reverse-loop x (nil)))
     (equal (divides x y)
	    (zerop (remainder y x)))
     (equal (assume-true var alist)
	    (cons (cons var (t))
		  alist))
     (equal (assume-false var alist)
	    (cons (cons var (f))
		  alist))
     (equal (tautology-checker x)
	    (tautologyp (normalize x)
			(nil)))
     (equal (falsify x)
	    (falsify1 (normalize x)
		      (nil)))
     (equal (prime x)
	    (and (not (zerop x))
		 (not (equal x (add1 (zero))))
		 (prime1 x (sub1 x))))
     (equal (and p q)
	    (if p (if q (t)
		    (f))
	      (f)))
     (equal (or p q)
	    (if p (t)
	      (if q (t)
		(f))))
     (equal (not p)
	    (if p (f)
	      (t)))
     (equal (implies p q)
	    (if p (if q (t)
		    (f))
	      (t)))
     (equal (fix x)
	    (if (numberp x)
		x
	      (zero)))
     (equal (if (if a b c)
		d e)
	    (if a (if b d e)
	      (if c d e)))
     (equal (zerop x)
	    (or (equal x (zero))
		(not (numberp x))))
     (equal (plus (plus x y)
		  z)
	    (plus x (plus y z)))
     (equal (equal (plus a b)
		   (zero))
	    (and (zerop a)
		 (zerop b)))
     (equal (difference x x)
	    (zero))
     (equal (equal (plus a b)
		   (plus a c))
	    (equal (fix b)
		   (fix c)))
     (equal (equal (zero)
		   (difference x y))
	    (not (lessp y x)))
     (equal (equal x (difference x y))
	    (and (numberp x)
		 (or (equal x (zero))
		     (zerop y))))
     (equal (meaning (plus-tree (append x y))
		     a)
	    (plus (meaning (plus-tree x)
			   a)
		  (meaning (plus-tree y)
			   a)))
     (equal (meaning (plus-tree (plus-fringe x))
		     a)
	    (fix (meaning x a)))
     (equal (append (append x y)
		    z)
	    (append x (append y z)))
     (equal (reverse (append a b))
	    (append (reverse b)
		    (reverse a)))
     (equal (times x (plus y z))
	    (plus (times x y)
		  (times x z)))
     (equal (times (times x y)
		   z)
	    (times x (times y z)))
     (equal (equal (times x y)
		   (zero))
	    (or (zerop x)
		(zerop y)))
     (equal (exec (append x y)
		  pds envrn)
	    (exec y (exec x pds envrn)
		  envrn))
     (equal (mc-flatten x y)
	    (append (flatten x)
		    y))
     (equal (member x (append a b))
	    (or (member x a)
		(member x b)))
     (equal (member x (reverse y))
	    (member x y))
     (equal (length (reverse x))
	    (length x))
     (equal (member a (intersect b c))
	    (and (member a b)
		 (member a c)))
     (equal (nth (zero)
		 i)
	    (zero))
     (equal (exp i (plus j k))
	    (times (exp i j)
		   (exp i k)))
     (equal (exp i (times j k))
	    (exp (exp i j)
		 k))
     (equal (reverse-loop x y)
	    (append (reverse x)
		    y))
     (equal (reverse-loop x (nil))
	    (reverse x))
     (equal (count-list z (sort-lp x y))
	    (plus (count-list z x)
		  (count-list z y)))
     (equal (equal (append a b)
		   (append a c))
	    (equal b c))
     (equal (plus (remainder x y)
		  (times y (quotient x y)))
	    (fix x))
     (equal (power-eval (big-plus1 l i base)
			base)
	    (plus (power-eval l base)
		  i))
     (equal (power-eval (big-plus x y i base)
			base)
	    (plus i (plus (power-eval x base)
			  (power-eval y base))))
     (equal (remainder y 1)
	    (zero))
     (equal (lessp (remainder x y)
		   y)
	    (not (zerop y)))
     (equal (remainder x x)
	    (zero))
     (equal (lessp (quotient i j)
		   i)
	    (and (not (zerop i))
		 (or (zerop j)
		     (not (equal j 1)))))
     (equal (lessp (remainder x y)
		   x)
	    (and (not (zerop y))
		 (not (zerop x))
		 (not (lessp x y))))
     (equal (power-eval (power-rep i base)
			base)
	    (fix i))
     (equal (power-eval (big-plus (power-rep i base)
				  (power-rep j base)
				  (zero)
				  base)
			base)
	    (plus i j))
     (equal (gcd x y)
	    (gcd y x))
     (equal (nth (append a b)
		 i)
	    (append (nth a i)
		    (nth b (difference i (length a)))))
     (equal (difference (plus x y)
			x)
	    (fix y))
     (equal (difference (plus y x)
			x)
	    (fix y))
     (equal (difference (plus x y)
			(plus x z))
	    (difference y z))
     (equal (times x (difference c w))
	    (difference (times c x)
			(times w x)))
     (equal (remainder (times x z)
		       z)
	    (zero))
     (equal (difference (plus b (plus a c))
			a)
	    (plus b c))
     (equal (difference (add1 (plus y z))
			z)
	    (add1 y))
     (equal (lessp (plus x y)
		   (plus x z))
	    (lessp y z))
     (equal (lessp (times x z)
		   (times y z))
	    (and (not (zerop z))
		 (lessp x y)))
     (equal (lessp y (plus x y))
	    (not (zerop x)))
     (equal (gcd (times x z)
		 (times y z))
	    (times z (gcd x y)))
     (equal (value (normalize x)
		   a)
	    (value x a))
     (equal (equal (flatten x)
		   (cons y (nil)))
	    (and (nlistp x)
		 (equal x y)))
     (equal (listp (gopher x))
	    (listp x))
     (equal (samefringe x y)
	    (equal (flatten x)
		   (flatten y)))
     (equal (equal (greatest-factor x y)
		   (zero))
	    (and (or (zerop y)
		     (equal y 1))
		 (equal x (zero))))
     (equal (equal (greatest-factor x y)
		   1)
	    (equal x 1))
     (equal (numberp (greatest-factor x y))
	    (not (and (or (zerop y)
			  (equal y 1))
		      (not (numberp x)))))
     (equal (times-list (append x y))
	    (times (times-list x)
		   (times-list y)))
     (equal (prime-list (append x y))
	    (and (prime-list x)
		 (prime-list y)))
     (equal (equal z (times w z))
	    (and (numberp z)
		 (or (equal z (zero))
		     (equal w 1))))
     (equal (greatereqp x y)
	    (not (lessp x y)))
     (equal (equal x (times x y))
	    (or (equal x (zero))
		(and (numberp x)
		     (equal y 1))))
     (equal (remainder (times y x)
		       y)
	    (zero))
     (equal (equal (times a b)
		   1)
	    (and (not (equal a (zero)))
		 (not (equal b (zero)))
		 (numberp a)
		 (numberp b)
		 (equal (sub1 a)
			(zero))
		 (equal (sub1 b)
			(zero))))
     (equal (lessp (length (delete x l))
		   (length l))
	    (member x l))
     (equal (sort2 (delete x l))
	    (delete x (sort2 l)))
     (equal (dsort x)
	    (sort2 x))
     (equal (length (cons x1
			  (cons x2
				(cons x3 (cons x4
					       (cons x5
						     (cons x6 x7)))))))
	    (plus 6 (length x7)))
     (equal (difference (add1 (add1 x))
			2)
	    (fix x))
     (equal (quotient (plus x (plus x y))
		      2)
	    (plus x (quotient y 2)))
     (equal (sigma (zero)
		   i)
	    (quotient (times i (add1 i))
		      2))
     (equal (plus x (add1 y))
	    (if (numberp y)
		(add1 (plus x y))
	      (add1 x)))
     (equal (equal (difference x y)
		   (difference z y))
	    (if (lessp x y)
		(not (lessp y z))
	      (if (lessp z y)
		  (not (lessp y x))
		(equal (fix x)
		       (fix z)))))
     (equal (meaning (plus-tree (delete x y))
		     a)
	    (if (member x y)
		(difference (meaning (plus-tree y)
				     a)
			    (meaning x a))
	      (meaning (plus-tree y)
		       a)))
     (equal (times x (add1 y))
	    (if (numberp y)
		(plus x (times x y))
	      (fix x)))
     (equal (nth (nil)
		 i)
	    (if (zerop i)
		(nil)
	      (zero)))
     (equal (last (append a b))
	    (if (listp b)
		(last b)
	      (if (listp a)
		  (cons (car (last a))
			b)
		b)))
     (equal (equal (lessp x y)
		   z)
	    (if (lessp x y)
		(equal (t) z)
	      (equal (f) z)))
     (equal (assignment x (append a b))
	    (if (assignedp x a)
		(assignment x a)
	      (assignment x b)))
     (equal (car (gopher x))
	    (if (listp x)
		(car (flatten x))
	      (zero)))
     (equal (flatten (cdr (gopher x)))
	    (if (listp x)
		(cdr (flatten x))
	      (cons (zero)
		    (nil))))
     (equal (quotient (times y x)
		      y)
	    (if (zerop y)
		(zero)
	      (fix x)))
     (equal (get j (set i val mem))
	    (if (eqp j i)
		val
	      (get j mem))))))

(defun add-lemma-list (list)
  (mapc #'add-lemma list))

(defun add-lemma (term)
  (if (and (consp term)
	   (eq (car term) 'equal)
	   (consp (cadr term)))
      (setf (get (car (cadr term)) 'lemmas)
	   (cons
	    term
	    (get (car (cadr term)) 'lemmas)))
    (error "ADD-LEMMA did not like term:  " term)))

  ; Translates a term by replacing its constructor symbols by symbol-records.

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;
  ; The second phase.
  ;
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun test (n)
  (let ((term (apply-subst
	       '((x f (plus (plus a b)
			    (plus c (zero))))
		 (y f (times (times a b)
			     (plus c d)))
		 (z f (reverse (append (append a b)
				       (nil))))
		 (u equal (plus a b)
		    (difference x y))
		 (w lessp (remainder a b)
		    (member a (length b))))
	       (do ((term
		     '(implies (and (implies x y)
				    (and (implies y z)
					 (and (implies z u)
					      (implies u w))))
			       (implies x w))
		     `(or ,term (f)))
		    (n n (1- n)))
		   ((zerop n) term)))))
    (tautp term)))

(defun apply-subst (alist term)
  (if (not (consp term))
      (let ((temp-temp (assoc term alist)))
	(if temp-temp
	    (cdr temp-temp)
	  term))
    (cons (car term)
	  (apply-subst-list alist (cdr term)))))

(defun apply-subst-list (alist list)
  (map 'list (lambda (l)
	       (apply-subst alist l)) list))

(defun tautp (x)
  (tautologyp (rewrite x) '() '()))

(defun tautologyp (x true-list false-list)
  (cond ((truep x true-list)   't)
	((falsep x false-list) 'nil)
	((not (consp x)) 'nil)
	((eq (car x) 'if)
	 (cond ((truep (cadr x) true-list)
		(tautologyp (caddr x) true-list false-list))
	       ((falsep (cadr x) false-list)
		(tautologyp (cadddr x) true-list false-list))
	       (t (and (tautologyp (caddr x)
				   (cons (cadr x) true-list)
				   false-list)
		       (tautologyp (cadddr x)
				   true-list
				   (cons (cadr x) false-list))))))
	(t 'nil)))

(defvar *rewrite-count* 0) ; sanity check

  ; The next procedure is Henry Baker's sharing CONS, which avoids
  ; allocation if the result is already in hand.
  ; The REWRITE and REWRITE-ARGS procedures have been modified to
  ; use SCONS instead of CONS.

(defun scons (x y original)
  (if (and (eq x (car original))
	   (eq y (cdr original)))
      original
    (cons x y)))

(defun rewrite (term)
  (incf *rewrite-count*)
  (if (not (consp term))
      term
    (rewrite-with-lemmas (scons (car term)
				(rewrite-args (cdr term))
				term)
			 (get (car term) 'lemmas))))

(defun rewrite-args (list)
  (if (null list)
      '()
    (scons (rewrite (car list))
	   (rewrite-args (cdr list))
	   list)))

(defvar unify-subst '*)

(defun rewrite-with-lemmas (term list)
  (cond ((null list) term)
	((one-way-unify term (cadr (car list)))
	 (rewrite (apply-subst unify-subst (caddr (car list)))))
	(t (rewrite-with-lemmas term (cdr list)))))

(defun one-way-unify (term1 term2)
  (setq unify-subst '())
  (one-way-unify1 term1 term2))

(defun one-way-unify1 (term1 term2)
  (cond ((not (consp term2))
	 (let ((temp-temp (assoc term2 unify-subst)))
	   (cond (temp-temp
		  (term-equal? term1 (cdr temp-temp)))
		 ((numberp term2)	; This bug fix makes
		  (equal term1 term2)) ; nboyer 10-25% slower!
		 (t
		  (setq unify-subst (cons (cons term2 term1)
					  unify-subst))
		  't))))
	((not (consp term1)) 'nil)
	((eq (car term1)
	     (car term2))
	 (one-way-unify1-list (cdr term1)
			      (cdr term2)))
	(t 'nil)))

(defun one-way-unify1-list (list1 list2)
  (cond ((null list1) (null list2))
	((null list2) 'nil)
	((one-way-unify1 (car list1) (car list2))
	 (one-way-unify1-list (cdr list1) (cdr list2)))
	(t 'nil)))

(defun falsep (x list)
  (or (term-equal? x false-term)
      (term-member? x list)))

(defun truep (x list)
  (or (term-equal? x true-term)
      (term-member? x list)))

(defvar false-term '(f))
(defvar true-term '(t))

(defun term-equal? (x y)
  (if (consp x)
      (and (consp y)
	   (eq (car x) (car y))
	   (term-args-equal? (cdr x) (cdr y)))
    (equal x y)))

(defun term-args-equal? (list1 list2)
  (cond ((null list1) (null list2))
	((null list2) 'nil)
	((term-equal? (car list1) (car list2))
	 (term-args-equal? (cdr list1) (cdr list2)))
	(t 'nil)))

(defun term-member? (x list)
  (member x list :test #'term-equal?))

(defun test-boyer (n)
  (setq *rewrite-count* 0)
  (let ((answer (test n)))
    (format t "~&~s" rewrite-count)))
From: Kenny Tilton
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <231Ac.189673$WA4.92392@twister.nyc.rr.com>
Anybody got the Linj output for the following? :) kt

Joe Marshall wrote:

> Andr� Thieme <······························@justmail.de> writes:
> 
> 
>>I would be interested to hear the opinion of some experienced
>>Lispnicks about what they think about the code which is used for the
>>Lisp examples.
>>
>>For example look at http://shootout.alioth.debian.org/bench/hash/hash.cmucl
> 
> 
> Never mind the Lisp code.  The `benchmarks' are useless and the
> methodology sucks.  How often do you need to pipe the result of
> Ackermann's function to the shell *really* fast?
> 
> Let's see how some of these other languages do on the Boyer benchmark.
> 
> ;;; Boyer benchmark, Bob Boyer + fixes by Henry Baker
> 
> (in-package "CL-USER")
> 
> (defun setup ()
>   (add-lemma-list
>    '((equal (compile form)
> 	    (reverse (codegen (optimize form)
> 			      (nil))))
>      (equal (eqp x y)
> 	    (equal (fix x)
> 		   (fix y)))
>      (equal (greaterp x y)
> 	    (lessp y x))
>      (equal (lesseqp x y)
> 	    (not (lessp y x)))
>      (equal (greatereqp x y)
> 	    (not (lessp x y)))
>      (equal (boolean x)
> 	    (or (equal x (t))
> 		(equal x (f))))
>      (equal (iff x y)
> 	    (and (implies x y)
> 		 (implies y x)))
>      (equal (even1 x)
> 	    (if (zerop x)
> 		(t)
> 	      (odd (sub1 x))))
>      (equal (countps- l pred)
> 	    (countps-loop l pred (zero)))
>      (equal (fact- i)
> 	    (fact-loop i 1))
>      (equal (reverse- x)
> 	    (reverse-loop x (nil)))
>      (equal (divides x y)
> 	    (zerop (remainder y x)))
>      (equal (assume-true var alist)
> 	    (cons (cons var (t))
> 		  alist))
>      (equal (assume-false var alist)
> 	    (cons (cons var (f))
> 		  alist))
>      (equal (tautology-checker x)
> 	    (tautologyp (normalize x)
> 			(nil)))
>      (equal (falsify x)
> 	    (falsify1 (normalize x)
> 		      (nil)))
>      (equal (prime x)
> 	    (and (not (zerop x))
> 		 (not (equal x (add1 (zero))))
> 		 (prime1 x (sub1 x))))
>      (equal (and p q)
> 	    (if p (if q (t)
> 		    (f))
> 	      (f)))
>      (equal (or p q)
> 	    (if p (t)
> 	      (if q (t)
> 		(f))))
>      (equal (not p)
> 	    (if p (f)
> 	      (t)))
>      (equal (implies p q)
> 	    (if p (if q (t)
> 		    (f))
> 	      (t)))
>      (equal (fix x)
> 	    (if (numberp x)
> 		x
> 	      (zero)))
>      (equal (if (if a b c)
> 		d e)
> 	    (if a (if b d e)
> 	      (if c d e)))
>      (equal (zerop x)
> 	    (or (equal x (zero))
> 		(not (numberp x))))
>      (equal (plus (plus x y)
> 		  z)
> 	    (plus x (plus y z)))
>      (equal (equal (plus a b)
> 		   (zero))
> 	    (and (zerop a)
> 		 (zerop b)))
>      (equal (difference x x)
> 	    (zero))
>      (equal (equal (plus a b)
> 		   (plus a c))
> 	    (equal (fix b)
> 		   (fix c)))
>      (equal (equal (zero)
> 		   (difference x y))
> 	    (not (lessp y x)))
>      (equal (equal x (difference x y))
> 	    (and (numberp x)
> 		 (or (equal x (zero))
> 		     (zerop y))))
>      (equal (meaning (plus-tree (append x y))
> 		     a)
> 	    (plus (meaning (plus-tree x)
> 			   a)
> 		  (meaning (plus-tree y)
> 			   a)))
>      (equal (meaning (plus-tree (plus-fringe x))
> 		     a)
> 	    (fix (meaning x a)))
>      (equal (append (append x y)
> 		    z)
> 	    (append x (append y z)))
>      (equal (reverse (append a b))
> 	    (append (reverse b)
> 		    (reverse a)))
>      (equal (times x (plus y z))
> 	    (plus (times x y)
> 		  (times x z)))
>      (equal (times (times x y)
> 		   z)
> 	    (times x (times y z)))
>      (equal (equal (times x y)
> 		   (zero))
> 	    (or (zerop x)
> 		(zerop y)))
>      (equal (exec (append x y)
> 		  pds envrn)
> 	    (exec y (exec x pds envrn)
> 		  envrn))
>      (equal (mc-flatten x y)
> 	    (append (flatten x)
> 		    y))
>      (equal (member x (append a b))
> 	    (or (member x a)
> 		(member x b)))
>      (equal (member x (reverse y))
> 	    (member x y))
>      (equal (length (reverse x))
> 	    (length x))
>      (equal (member a (intersect b c))
> 	    (and (member a b)
> 		 (member a c)))
>      (equal (nth (zero)
> 		 i)
> 	    (zero))
>      (equal (exp i (plus j k))
> 	    (times (exp i j)
> 		   (exp i k)))
>      (equal (exp i (times j k))
> 	    (exp (exp i j)
> 		 k))
>      (equal (reverse-loop x y)
> 	    (append (reverse x)
> 		    y))
>      (equal (reverse-loop x (nil))
> 	    (reverse x))
>      (equal (count-list z (sort-lp x y))
> 	    (plus (count-list z x)
> 		  (count-list z y)))
>      (equal (equal (append a b)
> 		   (append a c))
> 	    (equal b c))
>      (equal (plus (remainder x y)
> 		  (times y (quotient x y)))
> 	    (fix x))
>      (equal (power-eval (big-plus1 l i base)
> 			base)
> 	    (plus (power-eval l base)
> 		  i))
>      (equal (power-eval (big-plus x y i base)
> 			base)
> 	    (plus i (plus (power-eval x base)
> 			  (power-eval y base))))
>      (equal (remainder y 1)
> 	    (zero))
>      (equal (lessp (remainder x y)
> 		   y)
> 	    (not (zerop y)))
>      (equal (remainder x x)
> 	    (zero))
>      (equal (lessp (quotient i j)
> 		   i)
> 	    (and (not (zerop i))
> 		 (or (zerop j)
> 		     (not (equal j 1)))))
>      (equal (lessp (remainder x y)
> 		   x)
> 	    (and (not (zerop y))
> 		 (not (zerop x))
> 		 (not (lessp x y))))
>      (equal (power-eval (power-rep i base)
> 			base)
> 	    (fix i))
>      (equal (power-eval (big-plus (power-rep i base)
> 				  (power-rep j base)
> 				  (zero)
> 				  base)
> 			base)
> 	    (plus i j))
>      (equal (gcd x y)
> 	    (gcd y x))
>      (equal (nth (append a b)
> 		 i)
> 	    (append (nth a i)
> 		    (nth b (difference i (length a)))))
>      (equal (difference (plus x y)
> 			x)
> 	    (fix y))
>      (equal (difference (plus y x)
> 			x)
> 	    (fix y))
>      (equal (difference (plus x y)
> 			(plus x z))
> 	    (difference y z))
>      (equal (times x (difference c w))
> 	    (difference (times c x)
> 			(times w x)))
>      (equal (remainder (times x z)
> 		       z)
> 	    (zero))
>      (equal (difference (plus b (plus a c))
> 			a)
> 	    (plus b c))
>      (equal (difference (add1 (plus y z))
> 			z)
> 	    (add1 y))
>      (equal (lessp (plus x y)
> 		   (plus x z))
> 	    (lessp y z))
>      (equal (lessp (times x z)
> 		   (times y z))
> 	    (and (not (zerop z))
> 		 (lessp x y)))
>      (equal (lessp y (plus x y))
> 	    (not (zerop x)))
>      (equal (gcd (times x z)
> 		 (times y z))
> 	    (times z (gcd x y)))
>      (equal (value (normalize x)
> 		   a)
> 	    (value x a))
>      (equal (equal (flatten x)
> 		   (cons y (nil)))
> 	    (and (nlistp x)
> 		 (equal x y)))
>      (equal (listp (gopher x))
> 	    (listp x))
>      (equal (samefringe x y)
> 	    (equal (flatten x)
> 		   (flatten y)))
>      (equal (equal (greatest-factor x y)
> 		   (zero))
> 	    (and (or (zerop y)
> 		     (equal y 1))
> 		 (equal x (zero))))
>      (equal (equal (greatest-factor x y)
> 		   1)
> 	    (equal x 1))
>      (equal (numberp (greatest-factor x y))
> 	    (not (and (or (zerop y)
> 			  (equal y 1))
> 		      (not (numberp x)))))
>      (equal (times-list (append x y))
> 	    (times (times-list x)
> 		   (times-list y)))
>      (equal (prime-list (append x y))
> 	    (and (prime-list x)
> 		 (prime-list y)))
>      (equal (equal z (times w z))
> 	    (and (numberp z)
> 		 (or (equal z (zero))
> 		     (equal w 1))))
>      (equal (greatereqp x y)
> 	    (not (lessp x y)))
>      (equal (equal x (times x y))
> 	    (or (equal x (zero))
> 		(and (numberp x)
> 		     (equal y 1))))
>      (equal (remainder (times y x)
> 		       y)
> 	    (zero))
>      (equal (equal (times a b)
> 		   1)
> 	    (and (not (equal a (zero)))
> 		 (not (equal b (zero)))
> 		 (numberp a)
> 		 (numberp b)
> 		 (equal (sub1 a)
> 			(zero))
> 		 (equal (sub1 b)
> 			(zero))))
>      (equal (lessp (length (delete x l))
> 		   (length l))
> 	    (member x l))
>      (equal (sort2 (delete x l))
> 	    (delete x (sort2 l)))
>      (equal (dsort x)
> 	    (sort2 x))
>      (equal (length (cons x1
> 			  (cons x2
> 				(cons x3 (cons x4
> 					       (cons x5
> 						     (cons x6 x7)))))))
> 	    (plus 6 (length x7)))
>      (equal (difference (add1 (add1 x))
> 			2)
> 	    (fix x))
>      (equal (quotient (plus x (plus x y))
> 		      2)
> 	    (plus x (quotient y 2)))
>      (equal (sigma (zero)
> 		   i)
> 	    (quotient (times i (add1 i))
> 		      2))
>      (equal (plus x (add1 y))
> 	    (if (numberp y)
> 		(add1 (plus x y))
> 	      (add1 x)))
>      (equal (equal (difference x y)
> 		   (difference z y))
> 	    (if (lessp x y)
> 		(not (lessp y z))
> 	      (if (lessp z y)
> 		  (not (lessp y x))
> 		(equal (fix x)
> 		       (fix z)))))
>      (equal (meaning (plus-tree (delete x y))
> 		     a)
> 	    (if (member x y)
> 		(difference (meaning (plus-tree y)
> 				     a)
> 			    (meaning x a))
> 	      (meaning (plus-tree y)
> 		       a)))
>      (equal (times x (add1 y))
> 	    (if (numberp y)
> 		(plus x (times x y))
> 	      (fix x)))
>      (equal (nth (nil)
> 		 i)
> 	    (if (zerop i)
> 		(nil)
> 	      (zero)))
>      (equal (last (append a b))
> 	    (if (listp b)
> 		(last b)
> 	      (if (listp a)
> 		  (cons (car (last a))
> 			b)
> 		b)))
>      (equal (equal (lessp x y)
> 		   z)
> 	    (if (lessp x y)
> 		(equal (t) z)
> 	      (equal (f) z)))
>      (equal (assignment x (append a b))
> 	    (if (assignedp x a)
> 		(assignment x a)
> 	      (assignment x b)))
>      (equal (car (gopher x))
> 	    (if (listp x)
> 		(car (flatten x))
> 	      (zero)))
>      (equal (flatten (cdr (gopher x)))
> 	    (if (listp x)
> 		(cdr (flatten x))
> 	      (cons (zero)
> 		    (nil))))
>      (equal (quotient (times y x)
> 		      y)
> 	    (if (zerop y)
> 		(zero)
> 	      (fix x)))
>      (equal (get j (set i val mem))
> 	    (if (eqp j i)
> 		val
> 	      (get j mem))))))
> 
> (defun add-lemma-list (list)
>   (mapc #'add-lemma list))
> 
> (defun add-lemma (term)
>   (if (and (consp term)
> 	   (eq (car term) 'equal)
> 	   (consp (cadr term)))
>       (setf (get (car (cadr term)) 'lemmas)
> 	   (cons
> 	    term
> 	    (get (car (cadr term)) 'lemmas)))
>     (error "ADD-LEMMA did not like term:  " term)))
> 
>   ; Translates a term by replacing its constructor symbols by symbol-records.
> 
>   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>   ;
>   ; The second phase.
>   ;
>   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> (defun test (n)
>   (let ((term (apply-subst
> 	       '((x f (plus (plus a b)
> 			    (plus c (zero))))
> 		 (y f (times (times a b)
> 			     (plus c d)))
> 		 (z f (reverse (append (append a b)
> 				       (nil))))
> 		 (u equal (plus a b)
> 		    (difference x y))
> 		 (w lessp (remainder a b)
> 		    (member a (length b))))
> 	       (do ((term
> 		     '(implies (and (implies x y)
> 				    (and (implies y z)
> 					 (and (implies z u)
> 					      (implies u w))))
> 			       (implies x w))
> 		     `(or ,term (f)))
> 		    (n n (1- n)))
> 		   ((zerop n) term)))))
>     (tautp term)))
> 
> (defun apply-subst (alist term)
>   (if (not (consp term))
>       (let ((temp-temp (assoc term alist)))
> 	(if temp-temp
> 	    (cdr temp-temp)
> 	  term))
>     (cons (car term)
> 	  (apply-subst-list alist (cdr term)))))
> 
> (defun apply-subst-list (alist list)
>   (map 'list (lambda (l)
> 	       (apply-subst alist l)) list))
> 
> (defun tautp (x)
>   (tautologyp (rewrite x) '() '()))
> 
> (defun tautologyp (x true-list false-list)
>   (cond ((truep x true-list)   't)
> 	((falsep x false-list) 'nil)
> 	((not (consp x)) 'nil)
> 	((eq (car x) 'if)
> 	 (cond ((truep (cadr x) true-list)
> 		(tautologyp (caddr x) true-list false-list))
> 	       ((falsep (cadr x) false-list)
> 		(tautologyp (cadddr x) true-list false-list))
> 	       (t (and (tautologyp (caddr x)
> 				   (cons (cadr x) true-list)
> 				   false-list)
> 		       (tautologyp (cadddr x)
> 				   true-list
> 				   (cons (cadr x) false-list))))))
> 	(t 'nil)))
> 
> (defvar *rewrite-count* 0) ; sanity check
> 
>   ; The next procedure is Henry Baker's sharing CONS, which avoids
>   ; allocation if the result is already in hand.
>   ; The REWRITE and REWRITE-ARGS procedures have been modified to
>   ; use SCONS instead of CONS.
> 
> (defun scons (x y original)
>   (if (and (eq x (car original))
> 	   (eq y (cdr original)))
>       original
>     (cons x y)))
> 
> (defun rewrite (term)
>   (incf *rewrite-count*)
>   (if (not (consp term))
>       term
>     (rewrite-with-lemmas (scons (car term)
> 				(rewrite-args (cdr term))
> 				term)
> 			 (get (car term) 'lemmas))))
> 
> (defun rewrite-args (list)
>   (if (null list)
>       '()
>     (scons (rewrite (car list))
> 	   (rewrite-args (cdr list))
> 	   list)))
> 
> (defvar unify-subst '*)
> 
> (defun rewrite-with-lemmas (term list)
>   (cond ((null list) term)
> 	((one-way-unify term (cadr (car list)))
> 	 (rewrite (apply-subst unify-subst (caddr (car list)))))
> 	(t (rewrite-with-lemmas term (cdr list)))))
> 
> (defun one-way-unify (term1 term2)
>   (setq unify-subst '())
>   (one-way-unify1 term1 term2))
> 
> (defun one-way-unify1 (term1 term2)
>   (cond ((not (consp term2))
> 	 (let ((temp-temp (assoc term2 unify-subst)))
> 	   (cond (temp-temp
> 		  (term-equal? term1 (cdr temp-temp)))
> 		 ((numberp term2)	; This bug fix makes
> 		  (equal term1 term2)) ; nboyer 10-25% slower!
> 		 (t
> 		  (setq unify-subst (cons (cons term2 term1)
> 					  unify-subst))
> 		  't))))
> 	((not (consp term1)) 'nil)
> 	((eq (car term1)
> 	     (car term2))
> 	 (one-way-unify1-list (cdr term1)
> 			      (cdr term2)))
> 	(t 'nil)))
> 
> (defun one-way-unify1-list (list1 list2)
>   (cond ((null list1) (null list2))
> 	((null list2) 'nil)
> 	((one-way-unify1 (car list1) (car list2))
> 	 (one-way-unify1-list (cdr list1) (cdr list2)))
> 	(t 'nil)))
> 
> (defun falsep (x list)
>   (or (term-equal? x false-term)
>       (term-member? x list)))
> 
> (defun truep (x list)
>   (or (term-equal? x true-term)
>       (term-member? x list)))
> 
> (defvar false-term '(f))
> (defvar true-term '(t))
> 
> (defun term-equal? (x y)
>   (if (consp x)
>       (and (consp y)
> 	   (eq (car x) (car y))
> 	   (term-args-equal? (cdr x) (cdr y)))
>     (equal x y)))
> 
> (defun term-args-equal? (list1 list2)
>   (cond ((null list1) (null list2))
> 	((null list2) 'nil)
> 	((term-equal? (car list1) (car list2))
> 	 (term-args-equal? (cdr list1) (cdr list2)))
> 	(t 'nil)))
> 
> (defun term-member? (x list)
>   (member x list :test #'term-equal?))
> 
> (defun test-boyer (n)
>   (setq *rewrite-count* 0)
>   (let ((answer (test n)))
>     (format t "~&~s" rewrite-count)))

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <pan.2004.06.18.18.05.26.922430@evaluator.pt>
On Wed, 16 Jun 2004 19:19:26 +0000, Kenny Tilton wrote:

> Anybody got the Linj output for the following? :) kt

I did. It's really ugly! But I had to make a few changes (Linj is not
exactly Common Lisp).

However, I'm unsure I got it right.  For example, the last few lines are:

(defun test-boyer (n)
  (setq *rewrite-count* 0)
  (let ((answer (test n)))
    (format t "~&~s" rewrite-count)))

Shouldn't the reference rewrite-count be *rewrite-count* instead?

Are there any test cases to test the program correctness?

BTW, the Java file has 3285 lines (the linj/lisp file has 551).  The first
function has 371 lines in linj/lisp and 2970 in Java, being terminated
with 107 parenthesis. (Who said that Lisp is full of parenthesis?)

Best regards,

Antonio Leitao.
From: Joe Marshall
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <vfhoya8x.fsf@ccs.neu.edu>
Antonio Menezes Leitao <··············@evaluator.pt> writes:

> On Wed, 16 Jun 2004 19:19:26 +0000, Kenny Tilton wrote:
>
>> Anybody got the Linj output for the following? :) kt
>
> I did. It's really ugly! But I had to make a few changes (Linj is not
> exactly Common Lisp).
>
> However, I'm unsure I got it right.  For example, the last few lines are:
>
> (defun test-boyer (n)
>   (setq *rewrite-count* 0)
>   (let ((answer (test n)))
>     (format t "~&~s" rewrite-count)))
>
> Shouldn't the reference rewrite-count be *rewrite-count* instead?

Yes.  Typo.

> Are there any test cases to test the program correctness?

     n      rewrites

     0         95024
     1        591777
     2       1813975
     3       5375678
     4      16445406
     5      51507739
From: Kenny Tilton
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <ClJAc.123008$Nn4.27522337@twister.nyc.rr.com>
Joe Marshall wrote:
> Antonio Menezes Leitao <··············@evaluator.pt> writes:
> 
> 
>>On Wed, 16 Jun 2004 19:19:26 +0000, Kenny Tilton wrote:
>>
>>
>>>Anybody got the Linj output for the following? :) kt
>>
>>I did. It's really ugly! But I had to make a few changes (Linj is not
>>exactly Common Lisp).
>>
>>However, I'm unsure I got it right.  For example, the last few lines are:
>>
>>(defun test-boyer (n)
>>  (setq *rewrite-count* 0)
>>  (let ((answer (test n)))
>>    (format t "~&~s" rewrite-count)))
>>
>>Shouldn't the reference rewrite-count be *rewrite-count* instead?
> 
> 
> Yes.  Typo.
> 
> 
>>Are there any test cases to test the program correctness?
> 
> 
>      n      rewrites
> 
>      0         95024
>      1        591777
>      2       1813975
>      3       5375678
>      4      16445406
>      5      51507739

ok now we just need timing info, preferably from runs on the same system.

kenny

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <pan.2004.06.19.00.10.59.950079@evaluator.pt>
On Fri, 18 Jun 2004 21:42:58 +0000, Kenny Tilton wrote:

> 
> 
> Joe Marshall wrote:
>> Antonio Menezes Leitao <··············@evaluator.pt> writes:
>> 
>> 
>>>On Wed, 16 Jun 2004 19:19:26 +0000, Kenny Tilton wrote:
>>>
>>>
>>>>Anybody got the Linj output for the following? :) kt
>>>
>>>I did. It's really ugly! But I had to make a few changes (Linj is not
>>>exactly Common Lisp).
>>>
>>>However, I'm unsure I got it right.  For example, the last few lines are:
>>>
>>>(defun test-boyer (n)
>>>  (setq *rewrite-count* 0)
>>>  (let ((answer (test n)))
>>>    (format t "~&~s" rewrite-count)))
>>>
>>>Shouldn't the reference rewrite-count be *rewrite-count* instead?
>> 
>> 
>> Yes.  Typo.
>> 
>> 
>>>Are there any test cases to test the program correctness?
>> 
>> 
>>      n      rewrites
>> 
>>      0         95024
>>      1        591777
>>      2       1813975
>>      3       5375678
>>      4      16445406
>>      5      51507739
> 
> ok now we just need timing info, preferably from runs on the same system.
> 
> kenny

I'll try to do that later (first I must make it run correctly which I
couldn't do even in Common Lisp/CMUCL, much less in Linj).

You shouldn't expect suprises: Linj implementation of Lisp list operations
is not optimized and I didn't include any unnecessary type declarations so
I expect it to be extremely slow when compared with what you can get
from any good Common Lisp compiler.
From: Kenny Tilton
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <1gOAc.123076$Nn4.27616420@twister.nyc.rr.com>
Antonio Menezes Leitao wrote:
> On Fri, 18 Jun 2004 21:42:58 +0000, Kenny Tilton wrote:
> 
> 
>>
>>Joe Marshall wrote:
>>
>>>Antonio Menezes Leitao <··············@evaluator.pt> writes:
>>>
>>>
>>>
>>>>On Wed, 16 Jun 2004 19:19:26 +0000, Kenny Tilton wrote:
>>>>
>>>>
>>>>
>>>>>Anybody got the Linj output for the following? :) kt
>>>>
>>>>I did. It's really ugly! But I had to make a few changes (Linj is not
>>>>exactly Common Lisp).
>>>>
>>>>However, I'm unsure I got it right.  For example, the last few lines are:
>>>>
>>>>(defun test-boyer (n)
>>>> (setq *rewrite-count* 0)
>>>> (let ((answer (test n)))
>>>>   (format t "~&~s" rewrite-count)))
>>>>
>>>>Shouldn't the reference rewrite-count be *rewrite-count* instead?
>>>
>>>
>>>Yes.  Typo.
>>>
>>>
>>>
>>>>Are there any test cases to test the program correctness?
>>>
>>>
>>>     n      rewrites
>>>
>>>     0         95024
>>>     1        591777
>>>     2       1813975
>>>     3       5375678
>>>     4      16445406
>>>     5      51507739
>>
>>ok now we just need timing info, preferably from runs on the same system.
>>
>>kenny
> 
> 
> I'll try to do that later (first I must make it run correctly which I
> couldn't do even in Common Lisp/CMUCL, much less in Linj).
> 
> You shouldn't expect suprises: Linj implementation of Lisp list operations
> is not optimized and I didn't include any unnecessary type declarations so
> I expect it to be extremely slow when compared with what you can get
> from any good Common Lisp compiler.
> 

Perfect. Then I take the results to comp.lang.java.* and start a flame 
war with totally unsupported conclusions. The javans tune your code 
while they prove I am an idiot, but meanwhile we get Lisp (and Linj) 
onto radar in some javan minds. Then we send in Peter on a speaking tour 
of NGs to chat up PCLtB.

Will this also be a useful tool for enhancing Linj? Might show you where 
to tune internally, and mebbe show which declarations provide the 
biggest bang for the effort.

kenny

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87wu1z3w88.fsf_-_@evaluator.pt>
Antonio Menezes Leitao <··············@evaluator.pt> writes:

> You shouldn't expect suprises: Linj implementation of Lisp list operations
> is not optimized and I didn't include any unnecessary type declarations so
> I expect it to be extremely slow when compared with what you can get
> from any good Common Lisp compiler.

I must say I'm completely surprised with Java performance.

I finally found some time to improve Linj so that it could compile the
boyer benchmark with minimal type declarations.  I had to make a few
changes to the original boyer code because Linj semantics are a bit
different from Common Lisp in what regards nil.  In Linj, nil means
the boolean false, and '() (or 'nil) means the empty list.  This
difference is important for the type inference process.

To remove any timing differences due to those changes, I made them
both in the Common Lisp version and in the Linj version.

First, let's look at the differences between the original boyer
benchmark and my modifications:

1,4d0
< ;;; Boyer benchmark, Bob Boyer + fixes by Henry Baker
< 
< (in-package "CL-USER")
< 
9c5
<                               (nil))))
---
>                               (false))))
34c30
<             (reverse-loop x (nil)))
---
>             (reverse-loop x (false)))
45c41
<                         (nil)))
---
>                         (false)))
48c44
<                       (nil)))
---
>                       (false)))
153c149
<      (equal (reverse-loop x (nil))
---
>      (equal (reverse-loop x (false))
241c237
<                    (cons y (nil)))
---
>                    (cons y (false)))
337c333
<      (equal (nth (nil)
---
>      (equal (nth (false)
340c336
<               (nil)
---
>               (false)
366c362
<                     (nil))))
---
>                     (false))))
405c401
<                                        (nil))))
---
>                                        (false))))

So far, it's just a change from (nil) to (false).  If I'm not
mistaken, in the setup function it doesn't matter what symbol you use
in place of nil as long as it doesn't occurs as the first argument of
each "top-level" equal.  I choosed false but I could have choosen
something else.  Can some boyer-benchmark-expert confirm this?

431,432c427,429
<   (map 'list (lambda (l)
<                (apply-subst alist l)) list))
---
>   (mapcar (lambda (l)
>             (apply-subst alist l))
>           list))

Linj doesn't implement map (yet) so I changed it to mapcar.

438,440c435,437
<   (cond ((truep x true-list)   't)
<         ((falsep x false-list) 'nil)
<         ((not (consp x)) 'nil)
---
>   (cond ((truep x true-list)   t)
>         ((falsep x false-list) nil)
>         ((not (consp x)) nil)
452c449
<         (t 'nil)))
---
>         (t nil)))

Removed unecessary quotes that have different semantics in Linj (in
Linj, t is a boolean but 't is a symbol, nil is a boolean but 'nil is
a list).

483c480
< (defvar unify-subst '*)
---
> (defvar unify-subst '())

The initial value of the variable is not needed, so I changed it to
allow Linj to infer the proper type.

501c498
<                   (equal term1 term2))  ; nboyer 10-25% slower!
---
>                   (eql term1 term2))    ; nboyer 10-25% slower!

The equal doesn't seem necessary.  Linj doesn't implement equal so I
changed it to eql.

505,506c502,503
<                   't))))
<         ((not (consp term1)) 'nil)
---
>                   t))))
>         ((not (consp term1)) nil)
511c508
<         (t 'nil)))
---
>         (t nil)))
515c512
<         ((null list2) 'nil)
---
>         ((null list2) nil)
518c515
<         (t 'nil)))
---
>         (t nil)))

Removed quotes.

536c533
<     (equal x y)))
---
>     (eql x y)))

The equal doesn't seem necessary.  Linj doesn't implement equal so I
changed it to eql.

540c537
<         ((null list2) 'nil)
---
>         ((null list2) nil)
543c540
<         (t 'nil)))
---
>         (t nil)))

Removed quotes.

548a546
>   (setup)

Added a setup call before each test so that the situation becomes more
similar to Java where the setup must also be done on each test.

After these changes, I checked that the same results are obtained and
they matched exactly (to be honest, I just checked the output).  Here
are the timings (in seconds) for the original boyer benchmark versus
my modifications (using the form '(time (test-boyer n))' in CMU Common
Lisp CVS release-18e-branch + minimal debian patches, on a 1.6 Ghz
Centrino).

n original my modification
0   0.10    0.07
1   0.60    0.61
2   1.78    1.80
3   5.61    4.78
4   9.83   10.23
5  20.68   18.37

It looks like the changes have minimal impact on performance.

The modified boyer benchmark was then further modified to produce a
new version according to the Linj language.  Here are the differences
between both versions:

380c380
<     (setf (get (car (cadr term)) 'lemmas)
---
>     (setf (get (the symbol (car (cadr term))) 'lemmas)
383c383
<            (get (car (cadr term)) 'lemmas)))
---
>            (get (the symbol (car (cadr term))) 'lemmas '())))

A few typecasts where added because car returns an object and get must
know the type of the first argument (there are different get methods
in Linj).  Also, a default value for get was added because Linj's
default is null and not ().

471c471
<                          (get (car term) 'lemmas))))
---
>                          (get (the symbol (car term)) 'lemmas '()))))

Again, a typecast and a default for get.

542,543c542,543
< (defun term-member? (x list)
<   (member x list :test #'term-equal?))
---
> (defun term-member? (x list/cons)
>   (member x list :test #'(term-equal? object object)))

A type declaration was added (there are multiple member methods in
Linj).

550a551,553
> 
> (defun main (n/int)
>   (test-boyer n))

A main entry point was added.


In the boyer benchmark example, the translation from Common Lisp to
Linj was really simple (but I must confess that it uncovered a couple
of bugs in the Linj compiler).  Running the same tests produced the
same output as in Common Lisp.  I hope there's a strong correlation
between the program's output and its correctness as I don't have the
time to see if everything is OK. I just hope it is.

And now, the important results: timings for the Java version.  I used
the command 'time java -Xmx200m Boyer n' (java version "1.3.1"
Java(TM) 2 Runtime Environment, Standard Edition (build
Blackdown-1.3.1-02b-FCS) Java HotSpot(TM) Client VM (build
Blackdown-1.3.1_02b-FCS, mixed mode)):

n Common Lisp Java
0    0.07     2.72
1    0.61     3.21
2    1.80     4.64
3    4.78    8.121
4   10.23    13.56
5   18.37    25.77 

Note that the comparison is a bit unfair for the Java version as it
must load and unload the JVM and all necessary classes.  The Common
Lisp version was tested inside the CMUCL environment with all the
necessary stuff loaded so no CMUCL startup and shutdown time was
included.

I must stress that no optimization what so ever was done on the Linj
libraries needed for this example (namely the cons and the symbol
classes).  Just to see what was going on, I profiled the Java version
(with 'java -Xprof -Xmx200m Boyer 5') and here are the results:

Flat profile of 23.19 secs (330 total ticks): main

     Compiled + native   Method                        
 21.2%    64  +     0    Boyer.rewrite
 19.5%    59  +     0    java.util.Hashtable.get
  9.6%    29  +     0    Boyer.rewriteArgs
  8.9%    27  +     0    Boyer.oneWayUnify1
  6.0%    18  +     0    Boyer.rewriteWithLemmas
  4.6%    14  +     0    linj.Cons.find
  4.3%    13  +     0    java.lang.String.hashCode
  3.6%    11  +     0    linj.Cons.rest
  3.3%    10  +     0    linj.Cons.getf
  3.3%    10  +     0    Boyer.oneWayUnify1List
  3.3%    10  +     0    java.lang.String.equals
  2.6%     8  +     0    linj.Cons.first
  2.0%     6  +     0    linj.Cons.mapcar
  1.7%     5  +     0    linj.Cons$1.funcall
  1.7%     5  +     0    linj.Symbol.intern
  1.3%     4  +     0    linj.Predicate2$1.funcall
  1.3%     4  +     0    Boyer$3.funcall
  1.3%     4  +     0    Boyer.applySubst
 99.7%   301  +     0    Total compiled

  Thread-local ticks:
  8.5%    28             Blocked (of total)
  0.3%     1             Compilation


Flat profile of 0.01 secs (1 total ticks): DestroyJavaVM

  Thread-local ticks:
100.0%     1             Blocked (of total)


Global summary of 24.04 seconds:
100.0%   703             Received ticks
 52.8%   371             Received GC ticks
  0.1%     1             Compilation
  0.1%     1             Other VM operations


It looks like a large fraction (> 50%) of the time is spent in GC. In
the Common Lisp version the GC time was arount 10%.

I then decided to make a better comparison.  I decided to remove the
startup and shutdown time and also the time needed to run the setup
function that builds and processes a big list.  These modifications
where done both to the Common Lisp version and to the Linj version.

N Common Lisp Java
0   0.07      0.04
1   0.23      0.22
2   0.75      0.62
3   1.76      1.93
4   5.44      5.35
5  20.60     24.24

These are the results that really surprised me.  In the boyer
benchmark, Linj generates Java code that has more or less the same
performance as the Common Lisp original code.

Comments?


Appendix: I will not include the Common Lisp version as it was posted
already in this newsgroup.  But, for your amusement, I'll include
(part of) the Java version generated by the Linj compiler.

////////////////////////////////////////////////////////////////////////
import linj.Bignum;
import linj.Cons;
import linj.Function;
import linj.Predicate2;
import linj.Symbol;

public class Boyer extends Object {

    public static void setup() {
      //a 3000 lines method body
    }

    public static void addLemmaList(Cons list) {
        list.
         mapc(new Function() {
                  public Object funcall(Object arg) {
                      return addLemma(arg);
                  }});
    }

    public static Cons addLemma(Object term) {
        if (((term instanceof Cons) && (term != Cons.EMPTY_LIST)) &&
            (((Cons)term).car() == Symbol.intern("equal")) &&
            ((((Cons)term).cadr() instanceof Cons) && (((Cons)term).cadr() != Cons.EMPTY_LIST))) {
            return ((Symbol)((Cons)((Cons)term).cadr()).car()).
                    setfGet(new Cons(term,
                                     ((Symbol)((Cons)((Cons)term).cadr()).car()).
                                      get(Symbol.intern("lemmas"), Cons.EMPTY_LIST)),
                            Symbol.intern("lemmas"),
                            null);
        } else {
            throw new Error("ADD-LEMMA did not like term:  ");
        }
    }

    public static boolean test(Object n) {
        Object term =
            applySubst(Cons.
                        list(Cons.
                              list(Symbol.intern("x"),
                                   Symbol.intern("f"),
                                   Cons.
                                    list(Symbol.intern("plus"),
                                         Cons.list(Symbol.intern("plus"), Symbol.intern("a"), Symbol.intern("b")),
                                         Cons.
                                          list(Symbol.intern("plus"),
                                               Symbol.intern("c"),
                                               Cons.list(Symbol.intern("zero"))))),
                             Cons.
                              list(Symbol.intern("y"),
                                   Symbol.intern("f"),
                                   Cons.
                                    list(Symbol.intern("times"),
                                         Cons.list(Symbol.intern("times"), Symbol.intern("a"), Symbol.intern("b")),
                                         Cons.list(Symbol.intern("plus"), Symbol.intern("c"), Symbol.intern("d")))),
                             Cons.
                              list(Symbol.intern("z"),
                                   Symbol.intern("f"),
                                   Cons.
                                    list(Symbol.intern("reverse"),
                                         Cons.
                                          list(Symbol.intern("append"),
                                               Cons.
                                                list(Symbol.intern("append"), Symbol.intern("a"), Symbol.intern("b")),
                                               Cons.list(Symbol.intern("false"))))),
                             Cons.
                              list(Symbol.intern("u"),
                                   Symbol.intern("equal"),
                                   Cons.list(Symbol.intern("plus"), Symbol.intern("a"), Symbol.intern("b")),
                                   Cons.list(Symbol.intern("difference"), Symbol.intern("x"), Symbol.intern("y"))),
                             Cons.
                              list(Symbol.intern("w"),
                                   Symbol.intern("lessp"),
                                   Cons.list(Symbol.intern("remainder"), Symbol.intern("a"), Symbol.intern("b")),
                                   Cons.
                                    list(Symbol.intern("member"),
                                         Symbol.intern("a"),
                                         Cons.list(Symbol.intern("length"), Symbol.intern("b"))))),
                       new Object() {
                           public Cons funcall(final Object n) {
                               Cons term =
                                   Cons.
                                    list(Symbol.intern("implies"),
                                         Cons.
                                          list(Symbol.intern("and"),
                                               Cons.
                                                list(Symbol.intern("implies"), Symbol.intern("x"), Symbol.intern("y")),
                                               Cons.
                                                list(Symbol.intern("and"),
                                                     Cons.
                                                      list(Symbol.intern("implies"),
                                                           Symbol.intern("y"),
                                                           Symbol.intern("z")),
                                                     Cons.
                                                      list(Symbol.intern("and"),
                                                           Cons.
                                                            list(Symbol.intern("implies"),
                                                                 Symbol.intern("z"),
                                                                 Symbol.intern("u")),
                                                           Cons.
                                                            list(Symbol.intern("implies"),
                                                                 Symbol.intern("u"),
                                                                 Symbol.intern("w"))))),
                                         Cons.list(Symbol.intern("implies"), Symbol.intern("x"), Symbol.intern("w")));
                               for (Object n0 = n;
                                    ! (((Bignum)n0).compareTo(Bignum.valueOf(0)) == 0);
                                    term = new Cons(Symbol.intern("or"),
                                                    new Cons(term,
                                                             Cons.
                                                              list(Cons.list(Symbol.intern("f"))))), n0 = ((Bignum)n0).
                                                                                                           subtract(Bignum.
                                                                                                                     valueOf(1))) {
                               }
                               return term;
                           }}.
                        funcall(n));
        return tautp(term);
    }

    public static Object applySubst(Object alist, Object term) {
        if (! ((term instanceof Cons) && (term != Cons.EMPTY_LIST))) {
            Cons tempTemp = ((Cons)alist).assocKey(term, null, 1);
            if (! tempTemp.endp()) {
                return tempTemp.cdr();
            } else {
                return term;
            }
        } else {
            return new Cons(((Cons)term).car(), applySubstList(alist, (Cons)((Cons)term).cdr()));
        }
    }

    public static Cons applySubstList(final Object alist, Cons list) {
        return list.
                mapcar(new Function() {
                           public Object funcall(Object l) {
                               return applySubst(alist, l);
                           }});
    }

    public static boolean tautp(Object x) {
        return tautologyp(rewrite(x), Cons.EMPTY_LIST, Cons.EMPTY_LIST);
    }

    public static boolean tautologyp(Object x, Object trueList, Object falseList) {
        if (truep(x, trueList)) {
            return true;
        } else if (falsep(x, falseList)) {
            return false;
        } else if (! ((x instanceof Cons) && (x != Cons.EMPTY_LIST))) {
            return false;
        } else if (((Cons)x).car() == Symbol.intern("if")) {
            if (truep(((Cons)x).cadr(), trueList)) {
                return tautologyp(((Cons)((Cons)x).cddr()).car(), trueList, falseList);
            } else if (falsep(((Cons)x).cadr(), falseList)) {
                return tautologyp(((Cons)((Cons)x).cddr()).cadr(), trueList, falseList);
            } else {
                if (! tautologyp(((Cons)((Cons)x).cddr()).car(), new Cons(((Cons)x).cadr(), trueList), falseList)) {
                    return false;
                } else {
                    return tautologyp(((Cons)((Cons)x).cddr()).cadr(), trueList, new Cons(((Cons)x).cadr(), falseList));
                }
            }
        } else {
            return false;
        }
    }

    public static Cons scons(Object x, Object y, Cons original) {
        if ((x == original.car()) && (y == original.cdr())) {
            return original;
        } else {
            return new Cons(x, y);
        }
    }

    public static Object rewrite(Object term) {
        ++starRewriteCountStar;
        if (! ((term instanceof Cons) && (term != Cons.EMPTY_LIST))) {
            return term;
        } else {
            return rewriteWithLemmas(scons(((Cons)term).car(), rewriteArgs((Cons)((Cons)term).cdr()), (Cons)term),
                                     (Cons)((Symbol)((Cons)term).car()).get(Symbol.intern("lemmas"), Cons.EMPTY_LIST));
        }
    }

    public static Cons rewriteArgs(Cons list) {
        if (list.endp()) {
            return Cons.EMPTY_LIST;
        } else {
            return scons(rewrite(list.car()), rewriteArgs((Cons)list.cdr()), list);
        }
    }

    public static Object rewriteWithLemmas(Object term, Cons list) {
        if (list.endp()) {
            return term;
        } else if (oneWayUnify(term, ((Cons)list.car()).cadr())) {
            return rewrite(applySubst(unifySubst, ((Cons)((Cons)list.car()).cddr()).car()));
        } else {
            return rewriteWithLemmas(term, (Cons)list.cdr());
        }
    }

    public static boolean oneWayUnify(Object term1, Object term2) {
        unifySubst = Cons.EMPTY_LIST;
        return oneWayUnify1(term1, term2);
    }

    public static boolean oneWayUnify1(Object term1, Object term2) {
        if (! ((term2 instanceof Cons) && (term2 != Cons.EMPTY_LIST))) {
            Cons tempTemp = unifySubst.assocKey(term2, null, 1);
            if (! tempTemp.endp()) {
                return termEqualP(term1, tempTemp.cdr());
            } else if (term2 instanceof Number) {
                return (term1 == term2) ||
                       ((term1 instanceof Number) && (term2 instanceof Number) && term1.equals(term2));
            } else {
                unifySubst = new Cons(new Cons(term2, term1), unifySubst);
                return true;
            }
        } else if (! ((term1 instanceof Cons) && (term1 != Cons.EMPTY_LIST))) {
            return false;
        } else if (((Cons)term1).car() == ((Cons)term2).car()) {
            return oneWayUnify1List((Cons)((Cons)term1).cdr(), (Cons)((Cons)term2).cdr());
        } else {
            return false;
        }
    }

    public static boolean oneWayUnify1List(Cons list1, Cons list2) {
        if (list1.endp()) {
            return list2.endp();
        } else if (list2.endp()) {
            return false;
        } else if (oneWayUnify1(list1.car(), list2.car())) {
            return oneWayUnify1List((Cons)list1.cdr(), (Cons)list2.cdr());
        } else {
            return false;
        }
    }

    public static boolean falsep(Object x, Object list) {
        if (termEqualP(x, falseTerm)) {
            return true;
        } else {
            return ! termMemberP(x, (Cons)list).endp();
        }
    }

    public static boolean truep(Object x, Object list) {
        if (termEqualP(x, trueTerm)) {
            return true;
        } else {
            return ! termMemberP(x, (Cons)list).endp();
        }
    }

    public static boolean termEqualP(Object x, Object y) {
        if ((x instanceof Cons) && (x != Cons.EMPTY_LIST)) {
            if (! ((y instanceof Cons) && (y != Cons.EMPTY_LIST))) {
            return false;
        } else if (((Cons)x).car() != ((Cons)y).car()) {
            return false;
        } else {
            return termArgsEqualP((Cons)((Cons)x).cdr(), (Cons)((Cons)y).cdr());
        }
        } else {
            return (x == y) || ((x instanceof Number) && (y instanceof Number) && x.equals(y));
        }
    }

    public static boolean termArgsEqualP(Cons list1, Cons list2) {
        if (list1.endp()) {
            return list2.endp();
        } else if (list2.endp()) {
            return false;
        } else if (termEqualP(list1.car(), list2.car())) {
            return termArgsEqualP((Cons)list1.cdr(), (Cons)list2.cdr());
        } else {
            return false;
        }
    }

    public static Cons termMemberP(Object x, Cons list) {
        return list.
                memberKey(x,
                          new Predicate2() {
                              public boolean funcall(Object arg0, Object arg1) {
                                  return termEqualP(arg0, arg1);
                              }},
                          null,
                          3);
    }

    public static boolean testBoyer(Object n) {
        setup();
        starRewriteCountStar = 0;
        boolean answer = test(n);
        System.out.println();
        System.out.print(starRewriteCountStar);
        return answer;
    }

    public static void main(String[] outsideArgs) {
        int n = Integer.parseInt(outsideArgs[0]);
        testBoyer(Bignum.valueOf(n));
    }

    // slots

    public static int starRewriteCountStar = 0;

    public static Cons unifySubst = Cons.EMPTY_LIST;

    public static Cons falseTerm = Cons.list(Symbol.intern("f"));

    public static Cons trueTerm = Cons.list(Symbol.intern("t"));
}
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87oenaok6a.fsf@evaluator.pt>
Antonio Menezes Leitao <··············@evaluator.pt> writes:

> And now, the important results: timings for the Java version.  I used
> the command 'time java -Xmx200m Boyer n' (java version "1.3.1"
> Java(TM) 2 Runtime Environment, Standard Edition (build
> Blackdown-1.3.1-02b-FCS) Java HotSpot(TM) Client VM (build
> Blackdown-1.3.1_02b-FCS, mixed mode)):

A correction: the Java environment was java version "1.4.2_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_02-b03)
Java HotSpot(TM) Client VM (build 1.4.2_02-b03, mixed mode)

Sorry. (I was on the wrong shell when I tested 'java -version')

Ant�nio Leit�o.
From: Adam Warner
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <pan.2004.06.23.08.29.37.150632@consulting.net.nz>
Hi Antonio Menezes Leitao,

> A correction: the Java environment was java version "1.4.2_02"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_02-b03)
> Java HotSpot(TM) Client VM (build 1.4.2_02-b03, mixed mode)
                   ^^^^^^^^^
Try using the Server VM (-server command line option) for benchmarking and
also try tuning the GC options. Given your previous results I suspect you
will surpass CMUCL's performance using the Server VM.

Regards,
Adam
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87hdt2v9r7.fsf@evaluator.pt>
Adam Warner <······@consulting.net.nz> writes:

> Hi Antonio Menezes Leitao,
>
>> A correction: the Java environment was java version "1.4.2_02"
>> Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_02-b03)
>> Java HotSpot(TM) Client VM (build 1.4.2_02-b03, mixed mode)
>                    ^^^^^^^^^
> Try using the Server VM (-server command line option) for benchmarking and
> also try tuning the GC options. Given your previous results I suspect you
> will surpass CMUCL's performance using the Server VM.

Indeed.  I received a similar suggestion by email and I went for a new
run of tests.  I also tried other Common Lisp compilers.  Without
tuning the GC, I got:

N   CMUCL Allegro  CLISP  ClientVM  ServerVM
0    0.07    0.40   0.13   0.04     0.05  
1    0.61    0.27   0.83   0.24     0.13
2    1.80    0.74   2.32   0.62     0.39
3    4.78    2.08   6.61   1.93     1.08
4   10.23    6.55  17.89   5.34     3.67
5   18.37   28.32  69.43  22.15    15.98

I'm impressed!  It seems that Java compilers and virtual machines are
already competitive with Common Lisp compilers.  I'll will have to
look carefully at the Java code that was generated by the Linj
compiler to see if there's something unfair going on.  Maybe someone
can suggest another (similar) benchmark that has an easy proof of
correctness and that I might try to convert to Java.

Best regards,

Ant�nio Leit�o.
From: Dave Fayram
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <38ff3d6c.0406231311.45a4ec32@posting.google.com>
Antonio Menezes Leitao <··············@evaluator.pt> wrote in message news:mpilers.  Without

> N   CMUCL Allegro  CLISP  ClientVM  ServerVM
> 0    0.07    0.40   0.13   0.04     0.05  
> 1    0.61    0.27   0.83   0.24     0.13
> 2    1.80    0.74   2.32   0.62     0.39
> 3    4.78    2.08   6.61   1.93     1.08
> 4   10.23    6.55  17.89   5.34     3.67
> 5   18.37   28.32  69.43  22.15    15.98
> 

This scares me to my very core. What the heck is going on here?
Everyone getting soundly trounced? Even the expensive Allegro being
absolutely flattened by the Client VM? The only compiler that could
even keep up is the CMUCL compiler?

For awhile, I was laboring under the delusion that lisp produced
faster code than Java. This was kind of a holdout weapon for my
continued fight to get Lisp into more projects at my workplace (which
already has a few engineers that use SBCL to aid in formal
verification of Ada and C++ programs). Sure, Lisp may multiply a
developer's productivity, but that's entirely besides the point to
corporations choosing a development platform.

It was explained to me by someone in the unique position of being a
developer AND someone in upper management that the way that upper
management thinks is totally alien to most folks like us. They don't
warn more productive developers! They want average developers. He
explained to me that the time of companies with "good" and "bad"
programmers is labeled by many folks in upper management as a horrible
disaster.

Identifying talent is hard, and managers don't want to do hard work,
because if they mess up they get blamed and it destroys their career.
What they want are hundreds of identical cogs. Great for them because
then they're never be in the wrong, their careers are safe,  and when
they iron flat a company with "industry best practice," they move on
to the next giant with a clean slate and conscience. Tell one of these
guys that Java is "for the average programmer" and their eyes light
up. They hear it as, "for making programmers average." This is like,
the holy grail, the silver bullet. If they can't make all software
projects good, maybe they can keep all software projects from sucking
royally.

Total nonsense, of course. Time and time again, nimble startups with
talented people totally replace larger "average" companies. But
usually these startups are small and totally centered around their
talent. This is "amateurish" to the eyes of these folks. Of course,
many people would read "amateurish" as "not in need of dead-wood
blowhards who rake in cash and credit without regard." I mean, who
*wouldn't* want one of these guys around? Someone's gotta take all
that cash and press time. Right?

I think I am going to have trouble sleeping tonight. Java producing
faster code AND rounding out the averages? This Brave New World
terrifies me.
From: Carl Shapiro
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <ouyn02uapvs.fsf@panix3.panix.com>
·········@lensmen.net (Dave Fayram) writes:

> This scares me to my very core. What the heck is going on here?
> Everyone getting soundly trounced? Even the expensive Allegro being
> absolutely flattened by the Client VM? The only compiler that could
> even keep up is the CMUCL compiler?

Has anybody examined the size of the instruction vectors produced by
the competing compilers in this benchmark?  I suspect that all of
boyer fit neatly into the cache of evaluation machine making the
numbers produced from this benchmark rather uninteresting.  Besides,
it has been well know for over 10 years that boyer has lost its
meaning as a performance metric.  This comment (ca. February 1994)
from Henry Baker's C translation of boyer may be of interest.

/* Since this benchmark runs so fast on modern machines, Bob Boyer  */
/* (·····@cli.com) has produced two scalable "upgrades".  The first */
/* "SuperBoyer" simply changes slightly the original tautology to   */
/* produce more difficult problems based on a parameter N.  The     */
/* second "SuperDuperBoyer" uses the same framework to prove the    */
/* very hard "pigeonhole principle"--N+1 pigeons cannot be placed   */
/* in N holes, without at least one hole receiving two pigeons.     */
/* These upgrades can easily be made to this C version, as well.    */
From: Joe Marshall
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <zn6sg841.fsf@ccs.neu.edu>
Carl Shapiro <·············@panix.com> writes:

> Has anybody examined the size of the instruction vectors produced by
> the competing compilers in this benchmark?  I suspect that all of
> boyer fit neatly into the cache of evaluation machine making the
> numbers produced from this benchmark rather uninteresting.  Besides,
> it has been well know for over 10 years that boyer has lost its
> meaning as a performance metric.  This comment (ca. February 1994)
> from Henry Baker's C translation of boyer may be of interest.
>
> /* Since this benchmark runs so fast on modern machines, Bob Boyer  */
> /* (·····@cli.com) has produced two scalable "upgrades".  The first */
> /* "SuperBoyer" simply changes slightly the original tautology to   */
> /* produce more difficult problems based on a parameter N.  The     */
> /* second "SuperDuperBoyer" uses the same framework to prove the    */
> /* very hard "pigeonhole principle"--N+1 pigeons cannot be placed   */
> /* in N holes, without at least one hole receiving two pigeons.     */
> /* These upgrades can easily be made to this C version, as well.    */

Boyer may be a meaningless performance benchmark, but it is still a
damn sight better than `hello world', `loop 100000000', `fib(30)', and
the other crap that is measured.  I just tossed it out as an example.

I'll see if I can find some others.
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbf5uk$j7a$1@ulric.tng.de>
Dave Fayram schrieb:
> Antonio Menezes Leitao <··············@evaluator.pt> wrote in message news:mpilers.  Without
> 
> 
>>N   CMUCL Allegro  CLISP  ClientVM  ServerVM
>>0    0.07    0.40   0.13   0.04     0.05  
>>1    0.61    0.27   0.83   0.24     0.13
>>2    1.80    0.74   2.32   0.62     0.39
>>3    4.78    2.08   6.61   1.93     1.08
>>4   10.23    6.55  17.89   5.34     3.67
>>5   18.37   28.32  69.43  22.15    15.98
>>
> 
> 
> This scares me to my very core. What the heck is going on here?
> Everyone getting soundly trounced? Even the expensive Allegro being
> absolutely flattened by the Client VM? The only compiler that could
> even keep up is the CMUCL compiler?


Amazing results.
Now you wanted to show that Common Lisp runs its native code faster than 
Java, but with this test we found at least one area where Java is a lot 
faster. And I think in 1.5 it performs even better and I think the Java 
code can be optimized if it is written by an Java expert to become even 
faster, easily outperforming CL's native code.


> 
> For awhile, I was laboring under the delusion that lisp produced
> faster code than Java. This was kind of a holdout weapon for my
> continued fight to get Lisp into more projects at my workplace (which
> already has a few engineers that use SBCL to aid in formal
> verification of Ada and C++ programs). Sure, Lisp may multiply a
> developer's productivity, but that's entirely besides the point to
> corporations choosing a development platform.

With the new Java IDEs you can also multiply developers productivity. 
They auto generate so much code with a few keystrokes that static typing 
is not really a problem anymore.
The Java IDEs are probably 2-10 years ahead those for CL development.


Andr�
--
From: Dave Fayram
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <38ff3d6c.0406241615.1edc92da@posting.google.com>
Andr� Thieme <······························@justmail.de> wrote in message news:.
 
> With the new Java IDEs you can also multiply developers productivity. 
> They auto generate so much code with a few keystrokes that static typing 
> is not really a problem anymore.
> The Java IDEs are probably 2-10 years ahead those for CL development.

I don't find they multiply my productivity that much, but then I'm a
big fan of code generation and already used it a lot before I got into
Java (by way of Perl, then Ruby). Java's code browsers aren't all
that. The only place I've noticed really shine is in refactoring,
where they help manage type declarations and whatnot quite nicely.

If I have to choose between a good language and a mediocre environment
or a good environment and a mediocre language, I'll choose the former
every time.

- dlf
From: Tim Bradshaw
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <ey3659gm6vy.fsf@cley.com>
* Dave Fayram wrote:

> I don't find they multiply my productivity that much, but then I'm a
> big fan of code generation and already used it a lot before I got into
> Java (by way of Perl, then Ruby). Java's code browsers aren't all
> that. The only place I've noticed really shine is in refactoring,
> where they help manage type declarations and whatnot quite nicely.

I have a secret (no longer) theory that *nothing* makes much
difference to productivity in a repeatable way.  In particular someone
using vi, make gcc and gdb can be just productive than someone using
the most glamorous development environment.  This theory is based on a
fair amount of apocryphal but first-hand evidence: I know plenty of
people who use basically that environment, and they're employed and
paid plenty of money, and I'm sure they're very productive.

The same goes for many (not all) languages, I suspect, although for
more complicated reasons - Java has huge wins over C (GC & bounds
checking, which *are* huge wins before someone feels the need to be
nasty about how Java was a marketing trick), but makes up for it by
huge complexity of libraries.  Lisp has huge wins over C, but, well,
you have to put up with Lisp programmers. C++ is a counter example:
all the complexity but none of the benefits.

--tim (Actually this is pretty much Brooks' `No silver bullet'.  As so
       often, he was right.)
From: Ari Johnson
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <F4RCc.16309$Lh.13953@okepread01>
Tim Bradshaw wrote:
> The same goes for many (not all) languages, I suspect, although for
> more complicated reasons - Java has huge wins over C (GC & bounds
> checking, which *are* huge wins before someone feels the need to be
> nasty about how Java was a marketing trick), but makes up for it by
> huge complexity of libraries.  Lisp has huge wins over C, but, well,
> you have to put up with Lisp programmers. C++ is a counter example:
> all the complexity but none of the benefits.

Although I'm finding that there's little I am used to doing in C++ that 
I can't more readily do in Lisp, I still disagree.  C++ gives plenty of 
benefits over other languages.  For a C programmer, especially, its 
library is simpler than Java's.  It is faster than interpreted 
object-oriented languages.  It's one of the few languages with true 
multiple inheritance.  Bounds checking is there if you want it, gone if 
you don't.
From: Tim Bradshaw
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <fbc0f5d1.0406250712.17e210ad@posting.google.com>
Ari Johnson <·····@hotmail.com> wrote in message news:<····················@okepread01>...

> Although I'm finding that there's little I am used to doing in C++ that 
> I can't more readily do in Lisp, I still disagree.  C++ gives plenty of 
> benefits over other languages.

> For a C programmer, especially, its 
> library is simpler than Java's. 

Really?  Including the horrors like templates?  Smaller, probably, but
*simpler*?

> It is faster than interpreted 
> object-oriented languages.

C++ is not fast. Implementations may be.

> It's one of the few languages with true 
> multiple inheritance.

Now, what's the linearization rule again?  Oh, right, there isn't one.

> Bounds checking is there if you want it, gone if 
> you don't.

Right.  And not on by default for everything, unless you provide
special `turn it off, I am sure this is OK' options. And, actually,
don't you have to implement the bounds checking yourself?  Does the
standard library include bounds-checked versions of everything?

I'm sure there are *some* good things about C++, it's just very hard
to think of any.

--tim
From: Hannah Schroeter
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbhkrd$n3o$1@c3po.use.schlund.de>
Hello!

Tim Bradshaw <··········@tfeb.org> wrote:
>[...]

>I'm sure there are *some* good things about C++, it's just very hard
>to think of any.

In fact I've become to prefer C++ over C. Now, of course, what's that
comparison. But still: I need less manual memory management. I get
reference counting if I want, too, so even more less manual memory
management. I *know* that reference counting sucks big time in general
and that GCs both handle cycles and usually perform better than RC,
but still, given only the choice C++ vs. C, I'd still always take C++.

And I'm often only given that choice alas.

At least I'm able to sneak in some Lisp (or other less-sucky languages,
even wrote a little thing in Haskell which actually get deployed
[I delivered a native binary made with GHC, so those deploying it
could be agnostic about that it was in kinda Haskell], and something
in ocaml [I could deliver native binaries too]) here and there with the
official excuse of prototyping.

Kind regards,

Hannah.
From: Michael Walter
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <2k2u61F16sd93U1@uni-berlin.de>
Tim Bradshaw wrote:
> Ari Johnson <·····@hotmail.com> wrote in message news:<····················@okepread01>...
>>Although I'm finding that there's little I am used to doing in C++ that 
>>I can't more readily do in Lisp, I still disagree.  C++ gives plenty of 
>>benefits over other languages.
> 
>>For a C programmer, especially, its 
>>library is simpler than Java's. 
> 
> Really?  Including the horrors like templates?  Smaller, probably, but
> *simpler*?
Yeah.

>>It is faster than interpreted 
>>object-oriented languages.
> 
> 
> C++ is not fast. Implementations may be.
It surely is easier to write a fast C++ implementation than a fast 
<interpreted object-oriented language> implementation.

>>Bounds checking is there if you want it, gone if 
>>you don't.
> 
> 
> Right.  And not on by default for everything, unless you provide
> special `turn it off, I am sure this is OK' options.
Indeed, it's more like "I use the checked version if I want the checked 
version, I use the unchecked version otherwise".

> And, actually, don't you have to implement the bounds checking yourself?
No (when using the appropriate part of the standard library).

> Does the standard library include bounds-checked versions of everything?
Contrast .at() and operator[].

> I'm sure there are *some* good things about C++, it's just very hard
> to think of any.
It's easier if you actually try :)

Cheers,
Michael
From: Pascal Costanza
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <cbhk3l$fq4$1@newsreader2.netcologne.de>
Michael Walter wrote:
> Tim Bradshaw wrote:

>> C++ is not fast. Implementations may be.
> 
> It surely is easier to write a fast C++ implementation than a fast 
> <interpreted object-oriented language> implementation.

It's not that important how fast the implementation of a language is, 
it's more important how efficient the programmer is in developing an 
application, and maybe how fast the resulting application is. Common 
Lisp allows you to conveniently embed compilers for embedded 
domain-specific abstractions, whereas in C++ the natural way to model 
domain-specific abstractions is by writing interpreters.

These things are hard to measure with benchmarks.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Michael Walter
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <2k3391F17dv3eU1@uni-berlin.de>
Pascal Costanza wrote:
> Michael Walter wrote:
>> Tim Bradshaw wrote:
>>> C++ is not fast. Implementations may be.
>>
>> It surely is easier to write a fast C++ implementation than a fast 
>> <interpreted object-oriented language> implementation.
> 
> It's not that important how fast the implementation of a language is, 
> it's more important how efficient the programmer is in developing an 
> application, and maybe how fast the resulting application is.
The latter is obviously what both Ari and I meant.

Cheers,
Michael
From: Cameron MacKinnon
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <ArGdndtmgvJ-_kHdRVn-gQ@golden.net>
Michael Walter wrote:
> Pascal Costanza wrote:
> 
>> Michael Walter wrote:
>>
>>> Tim Bradshaw wrote:
>>>
>>>> C++ is not fast. Implementations may be.
>>>
>>>
>>> It surely is easier to write a fast C++ implementation than a fast 
>>> <interpreted object-oriented language> implementation.
>>
>>
>> It's not that important how fast the implementation of a language is, 
>> it's more important how efficient the programmer is in developing an 
>> application, and maybe how fast the resulting application is.
> 
> The latter is obviously what both Ari and I meant.
> 
> Cheers,
> Michael

Without defining what you're writing an implementation of, or which 
"interpreted OO language" we're comparing against, I find it hard to 
take your statement seriously.

Consider the options available to the poor competitor who is handicapped 
with the unnamed OO interpreter:

  - he can write a compiler for his language
  - he can run to the computer store and upgrade his CPU
  - he can work on a more efficient algorithm for his program

For some classes of problem, each of these three solutions might be 
faster than waiting for the C++ programmer to finish.

Are you saying that for ANY application x and OO interpreter y, it's 
easier to write a fast x in C++? I'd disagree.


-- 
Cameron MacKinnon
Toronto, Canada
From: Tim Bradshaw
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <fbc0f5d1.0406280226.711fde61@posting.google.com>
Michael Walter <··@leetspeak.org> wrote in message news:<···············@uni-berlin.de>...

> > Right.  And not on by default for everything, unless you provide
> > special `turn it off, I am sure this is OK' options.
> Indeed, it's more like "I use the checked version if I want the checked 
> version, I use the unchecked version otherwise".
> 

That's *exactly* the kind of approach which has got us into the
current quagmire of buffer overflow problems.  If it's not obvious to
you that you can *not* trust programmers to make these decisions, then
you should probably open your eyes.

There are really only two approaches which are viable in languages for
general use:

1. Mandatory bounds checking everywhere.

2. Mandatory bounds checking except in textually indicated regions of
code.

Java, I think, is in the former class, and there may be some CL
implementations there, CL is fairly close (but not close enough) to
being in the latter class, and some implementations probably are in
the latter class.  CL is fairly unusual in providing linguistic
support for textually marking regions of code as subject to differing
safety tradeoffs.

--tim
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbp3d3$65i$1@ulric.tng.de>
Tim Bradshaw schrieb:
> Michael Walter <··@leetspeak.org> wrote in message news:<···············@uni-berlin.de>...
> 
> 
>>>Right.  And not on by default for everything, unless you provide
>>>special `turn it off, I am sure this is OK' options.
>>
>>Indeed, it's more like "I use the checked version if I want the checked 
>>version, I use the unchecked version otherwise".
>>
> 
> 
> That's *exactly* the kind of approach which has got us into the
> current quagmire of buffer overflow problems.  If it's not obvious to
> you that you can *not* trust programmers to make these decisions, then
> you should probably open your eyes.
> 
> There are really only two approaches which are viable in languages for
> general use:
> 
> 1. Mandatory bounds checking everywhere.
> 
> 2. Mandatory bounds checking except in textually indicated regions of
> code.
> 
> Java, I think, is in the former class, and there may be some CL
> implementations there, CL is fairly close (but not close enough) to
> being in the latter class, and some implementations probably are in
> the latter class.  CL is fairly unusual in providing linguistic
> support for textually marking regions of code as subject to differing
> safety tradeoffs.

What are "textually indicated regions of code"?
How do I do that in CL and what happens then?


Andr�
--
From: Joe Marshall
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <k6xrera0.fsf@ccs.neu.edu>
Andr� Thieme <······························@justmail.de> writes:

> What are "textually indicated regions of code"?
> How do I do that in CL and what happens then?

You can do it a few ways.  Declaring the appropriate optimization
levels is the first thing you want to do, then you will want to
declare the types of variables and expressions.

A declaration in Common Lisp is a promise to the compiler that
you know something that it doesn't.  If you keep your promises, the
effect on the code can be a large increase in performance.  If you are
mistaken or lie, however, the effect is generally a crash of some
kind, not necessarily anywhere near where the buggy declaration is.
From: Raymond Wiker
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <86y8m7rgg6.fsf@raw.grenland.fast.no>
Andr� Thieme <······························@justmail.de> writes:

> Tim Bradshaw schrieb:
>> That's *exactly* the kind of approach which has got us into the
>> current quagmire of buffer overflow problems.  If it's not obvious to
>> you that you can *not* trust programmers to make these decisions, then
>> you should probably open your eyes.
>> There are really only two approaches which are viable in languages
>> for
>> general use:
>> 1. Mandatory bounds checking everywhere.
>> 2. Mandatory bounds checking except in textually indicated regions of
>> code.
>> Java, I think, is in the former class, and there may be some CL
>> implementations there, CL is fairly close (but not close enough) to
>> being in the latter class, and some implementations probably are in
>> the latter class.  CL is fairly unusual in providing linguistic
>> support for textually marking regions of code as subject to differing
>> safety tradeoffs.
>
> What are "textually indicated regions of code"?
> How do I do that in CL and what happens then?

        RTFHS[1] - in particular, you want to check up on DECLARE and
the scoping rules associated with it.

Footnotes: 
[1]  Read the *fine* HyperSpec.
From: Tim Bradshaw
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <ey3eknzchml.fsf@cley.com>
* Andr  wrote:

> What are "textually indicated regions of code"?

Regions of code that are marked in the code in such a way that
something which processes that code can find them, for instance to
allow automated or semi-automated auditing of the code.

(And please don't say `commenting convention').

> How do I do that in CL and what happens then?

Well:

(without-bounds-checking
 ...)

or

(with-unsafe-assumptions (:reference 1324)
  ...)

Where those macros expand to some combination of LOCALLY and DECLARE.

Note that CL *doesn't* completely support this sort of thing, because
there aren't enough promises in the standard about checking.
Implementations almost certainly do though (so long as you control the
compilation environment).

--tim
From: Paolo Amoroso
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87acyr95tx.fsf@plato.moon.paoloamoroso.it>
Tim Bradshaw <···@cley.com> writes:

> --tim (Actually this is pretty much Brooks' `No silver bullet'.  As so
>        often, he was right.)

What about Tim's `No Silver Choppers'? :)


Paolo
-- 
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Recommended Common Lisp libraries/tools (Google for info on each):
- ASDF/ASDF-INSTALL: system building/installation
- CL-PPCRE: regular expressions
- UFFI: Foreign Function Interface
From: Kenny Tilton
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <91%Cc.103$oW6.108780@twister.nyc.rr.com>
Paolo Amoroso wrote:

> Tim Bradshaw <···@cley.com> writes:
> 
> 
>>--tim (Actually this is pretty much Brooks' `No silver bullet'.  As so
>>       often, he was right.)
> 
> 
> What about Tim's `No Silver Choppers'? :)

Wrong again:

    http://www.bluemud.com/product.asp?dept_id=227&pf_id=92416&toc_id=320

kt

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Kenny Tilton
Subject: NSB? YSB! [was Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]]
Date: 
Message-ID: <iiXCc.18$oW6.65604@twister.nyc.rr.com>
Tim Bradshaw wrote:

> * Dave Fayram wrote:
> 
> 
>>I don't find they multiply my productivity that much, but then I'm a
>>big fan of code generation and already used it a lot before I got into
>>Java (by way of Perl, then Ruby). Java's code browsers aren't all
>>that. The only place I've noticed really shine is in refactoring,
>>where they help manage type declarations and whatnot quite nicely.
> 
> 
> I have a secret (no longer) theory that *nothing* makes much
> difference to productivity in a repeatable way.  In particular someone
> using vi, make gcc and gdb can be just productive than someone using
> the most glamorous development environment.  This theory is based on a
> fair amount of apocryphal but first-hand evidence: I know plenty of
> people who use basically that environment, and they're employed and
> paid plenty of money, and I'm sure they're very productive.
> 
> The same goes for many (not all) languages, I suspect, although for
> more complicated reasons - Java has huge wins over C (GC & bounds
> checking, which *are* huge wins before someone feels the need to be
> nasty about how Java was a marketing trick), but makes up for it by
> huge complexity of libraries.  Lisp has huge wins over C, but, well,
> you have to put up with Lisp programmers. C++ is a counter example:
> all the complexity but none of the benefits.
> 
> --tim (Actually this is pretty much Brooks' `No silver bullet'.  As so
>        often, he was right.)
> 

I think "all languages are created equal" is all yours when the next 
Bartlett's comes out. In Figure 16.1 of NSB Brooks bifurcates a dozen 
languages and one OS into the haves and have-nots. He also singles out 
Unix and <gasp!> Interlisp for a silver bullet award in that they were 
the first widely used "unified programming environments". Later on, when 
suggesting possible future silver bullets he writes "The hardest single 
part of building a software system is deciding precisely what to build." 
and then goes on to talk up iterative development/RAD. And some 
languages, I think we agree, are better than others for that.

This is one case where Brooks had the problem well-understood but missed 
the fact that the silver bullet (Lisp) was already in hand. And in one 
case he got even the analysis wrong, when he classified as "essential" 
(roughly, "inherent hence ineluctable") the exponential growth of 
application complexity with application size. Ironically, he holds up 
spreadsheets as a great silver bullet at the application level. Yet 
Steele's CLP in 84 demonstrated that spreadsheet-like automatic 
management of state change could relieve programmers of that burden.

kt

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Fred Gilham
Subject: Re: NSB? YSB! [was Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]]
Date: 
Message-ID: <u7smcj4gfw.fsf@snapdragon.csl.sri.com>
Kenny Tilton wrote:
> This is one case where Brooks had the problem well-understood but
> missed the fact that the silver bullet (Lisp) was already in
> hand. And in one case he got even the analysis wrong, when he
> classified as "essential" (roughly, "inherent hence ineluctable")
> the exponential growth of application complexity with application
> size. Ironically, he holds up spreadsheets as a great silver bullet
> at the application level. Yet Steele's CLP in 84 demonstrated that
> spreadsheet-like automatic management of state change could relieve
> programmers of that burden.

And I bet this posting didn't even come out of your advertising
budget! :-)

-- 
Fred Gilham                                        ······@csl.sri.com
The only people who would be hurt by abandoning the Kyoto Protocol
would be several thousand people who make a living attending
conferences on global warming.                  -- Kirill Kondratiev.
From: Kenny Tilton
Subject: Re: NSB? YSB! [was Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]]
Date: 
Message-ID: <QK%Cc.645$oW6.116444@twister.nyc.rr.com>
Fred Gilham wrote:

> Kenny Tilton wrote:
> 
>>This is one case where Brooks had the problem well-understood but
>>missed the fact that the silver bullet (Lisp) was already in
>>hand. And in one case he got even the analysis wrong, when he
>>classified as "essential" (roughly, "inherent hence ineluctable")
>>the exponential growth of application complexity with application
>>size. Ironically, he holds up spreadsheets as a great silver bullet
>>at the application level. Yet Steele's CLP in 84 demonstrated that
>>spreadsheet-like automatic management of state change could relieve
>>programmers of that burden.
> 
> 
> And I bet this posting didn't even come out of your advertising
> budget! :-)
> 

Nope, that's a copy-paste from something worked up by the orangutans 
over at Tilton Labs, our new think tank. They do want a chargeback to 
the advert dept, tho.

Brooks said this in NSB to support his assertion that complexity is one 
inherent property of the irreducible essense of software:

"The essence of a software entity is a construct of interlocking 
concepts: data sets, relationships among data items, algorithms, and 
invocations of functions."

Later...

"Digital computers themselves are more complex than most things people 
build; they have very large numbers of states. This makes conceiving, 
describing, and testing them hard. Software has orders of magnitude more 
states than computers do.

"Likewise, a scaling-up of a software entity...is necessarily an 
increase in the number of different elements. In most cases the elements 
interact with each other in some nonlinear fashion, and the complexity 
of the whole increases mush more than linearly."

Of course you as a garnet/kr fan know that bigger, fancier GUIs can be 
had with linearly more work. And Mark Giuliano uses the spreadsheet 
metaphor to explain COSI, so I wager he knows Brooks missed one.

Anyway, one thing Brooks said which might be taken to back up Tim's spin 
on NSB was that we could not expect a productivity leap from some new 
language, because languages already did everything we could possibly 
want: "language development approaches closer and closer to the 
sophistication of users". If he had been right, one could argue that any 
language that had adopted the latest developments in language design 
would be as productive as another.

kt

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Dave Fayram
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <38ff3d6c.0406241615.76b07dd9@posting.google.com>
Andr� Thieme <······························@justmail.de> wrote in message news:.
 
> With the new Java IDEs you can also multiply developers productivity. 
> They auto generate so much code with a few keystrokes that static typing 
> is not really a problem anymore.
> The Java IDEs are probably 2-10 years ahead those for CL development.

I don't find they multiply my productivity that much, but then I'm a
big fan of code generation and already used it a lot before I got into
Java (by way of Perl, then Ruby). Java's code browsers aren't all
that. The only place I've noticed really shine is in refactoring,
where they help manage type declarations and whatnot quite nicely.

If I have to choose between a good language and a mediocre environment
or a good environment and a mediocre language, I'll choose the former
every time.

- dlf
From: Ivan Boldyrev
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <b76uq1xd3r.ln2@ibhome.cgitftp.uiggm.nsc.ru>
--=-=-=
Content-Type: text/plain; charset=iso-8859-15
Content-Transfer-Encoding: quoted-printable

On 8786 day of my life Andr=E9 Thieme wrote:
> The Java IDEs are probably 2-10 years ahead those for CL development.

IDEs are 10 year ahead, but language is 30 years back.  10-30=3D20.  So,
Java is 20 year back... :)

=2D-=20
Ivan Boldyrev

        Outlook has performed an illegal operation and will be shut down.
        If the problem persists, contact the program vendor.

--=-=-=
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.3.6 (GNU/Linux)

iD8DBQBA3GnL4rmsj66VbhcRAl9sAJ9bJ+DbxMXkwZHs10HgbBlvrzTjjQCfajps
KaB3xevcCZUN23WlsNliIVU=
=ZMuP
-----END PGP SIGNATURE-----
--=-=-=--
From: =?ISO-8859-15?Q?Andr=E9_Thieme?=
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbijmr$s80$1@ulric.tng.de>
Ivan Boldyrev schrieb:
> On 8786 day of my life Andr� Thieme wrote:
> 
>>The Java IDEs are probably 2-10 years ahead those for CL development.
> 
> 
> IDEs are 10 year ahead, but language is 30 years back.  10-30=20.  So,
> Java is 20 year back... :)

Yup.
However, it seems Java is coming closer.
Don't forget that the development of the Java language is to some bigger 
parts in the hands of Guy Steele now, the creator of CL.
And as I said in another post already: they did a great job at Sun. Java 
was designed by a Lisper and is now improved by other Lispers. These 
guys understand how to build a language to be very successful.


Andr�
--
From: Peter Seibel
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <m3y8mb7wto.fsf@javamonkey.com>
Andr� Thieme <······························@justmail.de> writes:

> Ivan Boldyrev schrieb:
>> On 8786 day of my life Andr� Thieme wrote:
>>
>>>The Java IDEs are probably 2-10 years ahead those for CL
>>>development.

>> IDEs are 10 year ahead, but language is 30 years back. 10-30=20.
>> So, Java is 20 year back... :)
>
> Yup. However, it seems Java is coming closer. Don't forget that the
> development of the Java language is to some bigger parts in the
> hands of Guy Steele now, the creator of CL.

So I don't think that's a particularly accurate portrayal of Guy
Steele's role in Java. As I understand it (and I could swear I saw a
posting from him on the topic on some mailing list or at least someone
quoting him but Google isn't helping me out) he was brought in by Sun
to help write the spec after the language design was essentially
complete. Which he has done before--he is co-author of one of the
better C references though he did not, as far as I know, play any role
in the design of C.

> And as I said in another post already: they did a great job at Sun.
> Java was designed by a Lisper and is now improved by other Lispers.

That's not clear at all. To the extent a single person can be given
credit (blame?) for designing Java, it's James Gosling who is not, as
far as I know, "a Lisper". (Though I'm sure he has some familiarity
with Lisp being a well-educated guy and all that.)

-Peter


-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Thomas Lindgren
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <m34qoyze25.fsf@localhost.localdomain>
Peter Seibel <·····@javamonkey.com> writes:

> That's not clear at all. To the extent a single person can be given
> credit (blame?) for designing Java, it's James Gosling who is not, as
> far as I know, "a Lisper". (Though I'm sure he has some familiarity
> with Lisp being a well-educated guy and all that.)

Gosling also wrote Gosling emacs, which was programmed in Mocklisp.

Best,
                        Thomas
-- 
Thomas Lindgren
"It's becoming popular? It must be in decline." -- Isaiah Berlin
 
From: David Golden
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <NsdDc.3215$Z14.4093@news.indigo.ie>
Peter Seibel wrote:

> That's not clear at all. To the extent a single person can be given
> credit (blame?) for designing Java, it's James Gosling who is not, as
> far as I know, "a Lisper". (Though I'm sure he has some familiarity
> with Lisp being a well-educated guy and all that.)
> 

No, Gosling is _very_ familiar with Lisp...

But he is apparently a Dark Lisper, believing the power of Lisp should be
hoarded for an elite while java is good enough for the masses.
From: Rainer Joswig
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <c366f098.0406260745.6cc1edf@posting.google.com>
Andr� Thieme <······························@justmail.de> wrote in message news:<············@ulric.tng.de>...
> Ivan Boldyrev schrieb:
> > On 8786 day of my life Andr� Thieme wrote:
> > 
> >>The Java IDEs are probably 2-10 years ahead those for CL development.
> > 
> > 
> > IDEs are 10 year ahead, but language is 30 years back.  10-30=20.  So,
> > Java is 20 year back... :)
> 
> Yup.
> However, it seems Java is coming closer.
> Don't forget that the development of the Java language is to some bigger 
> parts in the hands of Guy Steele now, the creator of CL.

Guy Steele is NOT the creator of CL.

> And as I said in another post already: they did a great job at Sun. Java 
> was designed by a Lisper and is now improved by other Lispers. These 
> guys understand how to build a language to be very successful.
> 
> 
> Andr�
> --
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbln7q$ra8$2@ulric.tng.de>
Rainer Joswig schrieb:

> Andr� Thieme <······························@justmail.de> wrote in message news:<············@ulric.tng.de>...
> 
>>Ivan Boldyrev schrieb:
>>
>>>On 8786 day of my life Andr� Thieme wrote:
>>>
>>>
>>>>The Java IDEs are probably 2-10 years ahead those for CL development.
>>>
>>>
>>>IDEs are 10 year ahead, but language is 30 years back.  10-30=20.  So,
>>>Java is 20 year back... :)
>>
>>Yup.
>>However, it seems Java is coming closer.
>>Don't forget that the development of the Java language is to some bigger 
>>parts in the hands of Guy Steele now, the creator of CL.
> 
> 
> Guy Steele is NOT the creator of CL.


Who was it?
And what was Guys role?


Andr�
--
From: Rainer Joswig
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <joswig-76DAA4.10090327062004@individual.net>
In article <············@ulric.tng.de>,
 Andr� Thieme <······························@justmail.de> wrote:

> Rainer Joswig schrieb:
> 
> > Andr� Thieme <······························@justmail.de> wrote in message news:<············@ulric.tng.de>...
> > 
> >>Ivan Boldyrev schrieb:
> >>
> >>>On 8786 day of my life Andr� Thieme wrote:
> >>>
> >>>
> >>>>The Java IDEs are probably 2-10 years ahead those for CL development.
> >>>
> >>>
> >>>IDEs are 10 year ahead, but language is 30 years back.  10-30=20.  So,
> >>>Java is 20 year back... :)
> >>
> >>Yup.
> >>However, it seems Java is coming closer.
> >>Don't forget that the development of the Java language is to some bigger 
> >>parts in the hands of Guy Steele now, the creator of CL.
> > 
> > 
> > Guy Steele is NOT the creator of CL.
> 
> 
> Who was it?
> And what was Guys role?
> 
> 
> Andr�
> --

Common Lisp was designed by a group of people.
ANSI Common Lisp is the result of the work of
the members of the ANSI committee X3J13.
Steele wrote two books on an early versions of
Common Lisp (before ANSI Common Lisp) and he was one
of the main contributors.

The long story can be read in "The Evolution of Lisp" by Guy L. Steele Jr.
and Richard P. Gabriel. For example here:
http://www.dreamsongs.com/NewFiles/HOPL2-Uncut.pdf
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbmhok$e4g$1@ulric.tng.de>
Rainer Joswig schrieb:
> In article <············@ulric.tng.de>,
>  Andr� Thieme <······························@justmail.de> wrote:
> 
> 
>>Rainer Joswig schrieb:
>>
>>
>>>Andr� Thieme <······························@justmail.de> wrote in message news:<············@ulric.tng.de>...
>>>
>>>
>>>>Ivan Boldyrev schrieb:
>>>>
>>>>
>>>>>On 8786 day of my life Andr� Thieme wrote:
>>>>>
>>>>>
>>>>>
>>>>>>The Java IDEs are probably 2-10 years ahead those for CL development.
>>>>>
>>>>>
>>>>>IDEs are 10 year ahead, but language is 30 years back.  10-30=20.  So,
>>>>>Java is 20 year back... :)
>>>>
>>>>Yup.
>>>>However, it seems Java is coming closer.
>>>>Don't forget that the development of the Java language is to some bigger 
>>>>parts in the hands of Guy Steele now, the creator of CL.
>>>
>>>
>>>Guy Steele is NOT the creator of CL.
>>
>>
>>Who was it?
>>And what was Guys role?
>>
>>
>>Andr�
>>--
> 
> 
> Common Lisp was designed by a group of people.
> ANSI Common Lisp is the result of the work of
> the members of the ANSI committee X3J13.
> Steele wrote two books on an early versions of
> Common Lisp (before ANSI Common Lisp) and he was one
> of the main contributors.
> 
> The long story can be read in "The Evolution of Lisp" by Guy L. Steele Jr.
> and Richard P. Gabriel. For example here:
> http://www.dreamsongs.com/NewFiles/HOPL2-Uncut.pdf

Looks like a nice read, thanks!


Andr�
--
From: Pascal Costanza
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbjh90$5aa$1@newsreader2.netcologne.de>
Andr� Thieme wrote:
> Ivan Boldyrev schrieb:
> 
>> On 8786 day of my life Andr� Thieme wrote:
>>
>>> The Java IDEs are probably 2-10 years ahead those for CL development.
>>
>> IDEs are 10 year ahead, but language is 30 years back.  10-30=20.  So,
>> Java is 20 year back... :)
> 
> Yup.
> However, it seems Java is coming closer.
> Don't forget that the development of the Java language is to some bigger 
> parts in the hands of Guy Steele now, the creator of CL.

Incorrect. The person who is currently responsible for maintaining the 
Java language specification at Sun is Gilad Bracha. If you ask him he 
will tell you that Java's evolution is mainly dictated by political 
considerations and by people having influence on the right people in 
charge (i.e., managers, not technical people).

> And as I said in another post already: they did a great job at Sun. Java 
> was designed by a Lisper and is now improved by other Lispers. These 
> guys understand how to build a language to be very successful.

If you want to hear a statement by Guy Steele himself about his role in 
the design of Java, watch the quicktime movie on language design at 
http://www.ai.mit.edu/projects/dynlangs/wizards-panels.html

Just because his name is on the book cover doesn't mean anything. Those 
people also just have day jobs as everyone else.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: David Magda
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <86n02qfgnc.fsf@number6.magda.ca>
Pascal Costanza <········@web.de> writes:

> If you want to hear a statement by Guy Steele himself about his
> role in the design of Java, watch the quicktime movie on language
> design at
> http://www.ai.mit.edu/projects/dynlangs/wizards-panels.html

The movies are no longer online, and the Internet Way Back Machine
doesn't have them cached [1]. The streams also do not seem to ever
connect to which ever server they're being requested from.


[1] http://web.archive.org/web/*/http://www.ai.mit.edu/projects/dynlangs/wizards-panels.html

-- 
David Magda <dmagda at ee.ryerson.ca>, http://www.magda.ca/
Because the innovator has for enemies all those who have done well under
the old conditions, and lukewarm defenders in those who may do well 
under the new. -- Niccolo Machiavelli, _The Prince_, Chapter VI
From: Justin Dubs
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <2e262238.0406270016.2bcca4d3@posting.google.com>
David Magda <··················@ee.ryerson.ca> wrote in message news:<··············@number6.magda.ca>...
> Pascal Costanza <········@web.de> writes:
> 
> > If you want to hear a statement by Guy Steele himself about his
> > role in the design of Java, watch the quicktime movie on language
> > design at
> > http://www.ai.mit.edu/projects/dynlangs/wizards-panels.html
> 
> The movies are no longer online, and the Internet Way Back Machine
> doesn't have them cached [1]. The streams also do not seem to ever
> connect to which ever server they're being requested from.
> 
> 
> [1] http://web.archive.org/web/*/http://www.ai.mit.edu/projects/dynlangs/wizards-panels.html

I have the original, full-size quicktimes of all three sessions of the
Dynamic Language Wizards.  I do not, however, have any place
accessible to put them at the moment.

I believe it is legal for me to redistribute them, as they bare no
copyright notice of any kind either on the website or in the movies
themselves which I think makes them public domain.  Someone more
legally knowledgeable is welcome to jump in here and correct me...

If anyone has a place to host them, I'd be more than happy to send you
a copy.

I also don't mind arranging ways to send them off to individuals
within the confines of my free time and patience.  :-)

Post and/or email me if you want them.

Justin Dubs
From: Hannah Schroeter
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbmc0q$m6j$1@c3po.use.schlund.de>
Hello!

Justin Dubs <······@eos.ncsu.edu> wrote:
>[...]

>I believe it is legal for me to redistribute them, as they bare no
>copyright notice of any kind either on the website or in the movies
>themselves which I think makes them public domain.  Someone more
>legally knowledgeable is welcome to jump in here and correct me...

Nope.

Copyright is automatic.

The only thing you can conclude from them having been on a web site
is that the copyright holder might have consented that people download
it for viewing (but not for passing it on). In doubt, the removal
of that website might mean the copyright holder retracted his/her
(implicit) consent for redistribution at all.

Public domain is only when the copyright holder *explicitly* revokes
his/her copyright protections (where that is legally possible, in Germany
you *can't* give up some parts of copyright at all!).

>[...]

Kind regards,

Hannah.
From: Pascal Costanza
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbjlr0$dap$1@newsreader2.netcologne.de>
Pascal Costanza wrote:

> Incorrect. The person who is currently responsible for maintaining the 
> Java language specification at Sun is Gilad Bracha.

BTW, here is what he had to say about a proposal to add macros to Java: 
http://www.artima.com/weblogs/viewpost.jsp?thread=5246

Java and Lisp clearly target different audiences.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: =?ISO-8859-15?Q?Andr=E9_Thieme?=
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbmioa$esk$1@ulric.tng.de>
Pascal Costanza schrieb:

> 
> Andr� Thieme wrote:
> 
>> Ivan Boldyrev schrieb:
>>
>>> On 8786 day of my life Andr� Thieme wrote:
>>>
>>>> The Java IDEs are probably 2-10 years ahead those for CL development.
>>>
>>>
>>> IDEs are 10 year ahead, but language is 30 years back.  10-30=20.  So,
>>> Java is 20 year back... :)
>>
>>
>> Yup.
>> However, it seems Java is coming closer.
>> Don't forget that the development of the Java language is to some 
>> bigger parts in the hands of Guy Steele now, the creator of CL.
> 
> 
> Incorrect. The person who is currently responsible for maintaining the 
> Java language specification at Sun is Gilad Bracha. If you ask him he 
> will tell you that Java's evolution is mainly dictated by political 
> considerations and by people having influence on the right people in 
> charge (i.e., managers, not technical people).

Okay, thanks for the clarification.
However, I consciously said "to some bigger parts", as this sounds to be 
general enough to me, to still be true.

The article found here:
http://java.sun.com/features/2003/05/steele_qa.html
gave me the impression, that Guy can take influence on the development 
of Java:
"Guy Steele, a Sun Fellow at Sun Microsystems, is responsible for 
research in language design and implementation strategies, architectural 
and software support, and for the specification of the Java programming 
language."

And there were some other postings, originally found at
http://www.ai.mit.edu/~gregs/ll1-discuss-archive-html/maillist.html
which is now offline. One of them I found again here:
http://madbean.com/blog/49/

And this also made me think that if some language improvement is going 
to be in Java Guy is asked about his opinion about it.


>> And as I said in another post already: they did a great job at Sun. 
>> Java was designed by a Lisper and is now improved by other Lispers. 
>> These guys understand how to build a language to be very successful.
> 
> 
> If you want to hear a statement by Guy Steele himself about his role in 
> the design of Java, watch the quicktime movie on language design at 
> http://www.ai.mit.edu/projects/dynlangs/wizards-panels.html
> 
> Just because his name is on the book cover doesn't mean anything. Those 
> people also just have day jobs as everyone else.

Yes okay, thanks.
I wrote an email to the webmaster, asking about the videos.


Andr�
--
From: Pascal Costanza
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbmk5a$73n$1@newsreader2.netcologne.de>
Andr� Thieme wrote:

> And there were some other postings, originally found at
> http://www.ai.mit.edu/~gregs/ll1-discuss-archive-html/maillist.html
> which is now offline. One of them I found again here:
> http://madbean.com/blog/49/
> 
> And this also made me think that if some language improvement is going 
> to be in Java Guy is asked about his opinion about it.

If you read that comment carefully enough, you will notice that it is 
about a language feature that he (and others) were _not_ able to add to 
Java because of community pressure.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: =?ISO-8859-15?Q?Andr=E9_Thieme?=
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbmla4$gl6$1@ulric.tng.de>
Pascal Costanza schrieb:
> 
> Andr� Thieme wrote:
> 
>> And there were some other postings, originally found at
>> http://www.ai.mit.edu/~gregs/ll1-discuss-archive-html/maillist.html
>> which is now offline. One of them I found again here:
>> http://madbean.com/blog/49/
>>
>> And this also made me think that if some language improvement is going 
>> to be in Java Guy is asked about his opinion about it.
> 
> 
> If you read that comment carefully enough, you will notice that it is 
> about a language feature that he (and others) were _not_ able to add to 
> Java because of community pressure.

Exactly.
Anyway, the important fact for me is, that he is talking about it as if 
he is one of the Guys who can have some influence.


Andr�
--
From: Julian Stecklina
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <86hdswd94x.fsf@goldenaxe.localnet>
Andr� Thieme <······························@justmail.de> writes:

> Sun. Java was designed by a Lisper and is now improved by other
> Lispers. These guys understand how to build a language to be very
> successful.

Mmh... It might sound like herecy, /but/ why is Lisp not "very
successful"?

Regards,
-- 
Julian Stecklina 

Signed/encrypted mail welcome.  Key-ID: 0xD65B2AB5

-> GIVE stylish confetti to HEAVILY ARMED CLOWN <-
-> Heavily Armed Clown: Wheeee!!                <-
From: Tayssir John Gabbour
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <866764be.0406260802.67b2a349@posting.google.com>
Andr� Thieme <······························@justmail.de> wrote in message news:<············@ulric.tng.de>...
> With the new Java IDEs you can also multiply developers productivity. 
> They auto generate so much code with a few keystrokes that static typing 
> is not really a problem anymore.
> The Java IDEs are probably 2-10 years ahead those for CL development.

Which IDE's? IntelliJ's and that one reversible debugger?

My purpose is not to argue, simply understand.
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbln5a$ra8$1@ulric.tng.de>
Tayssir John Gabbour schrieb:
> Andr� Thieme <······························@justmail.de> wrote in message news:<············@ulric.tng.de>...
> 
>>With the new Java IDEs you can also multiply developers productivity. 
>>They auto generate so much code with a few keystrokes that static typing 
>>is not really a problem anymore.
>>The Java IDEs are probably 2-10 years ahead those for CL development.
> 
> 
> Which IDE's? IntelliJ's and that one reversible debugger?
> 
> My purpose is not to argue, simply understand.

Yes, idea and eclipse.


Andr�
--
From: Kenny Tilton
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <ctgCc.223294$WA4.186323@twister.nyc.rr.com>
Antonio Menezes Leitao wrote:
> Indeed.  I received a similar suggestion by email and I went for a new
> run of tests.  I also tried other Common Lisp compilers.  Without
> tuning the GC, I got:
> 
> N   CMUCL Allegro  CLISP  ClientVM  ServerVM
> 0    0.07    0.40   0.13   0.04     0.05  
> 1    0.61    0.27   0.83   0.24     0.13
> 2    1.80    0.74   2.32   0.62     0.39
> 3    4.78    2.08   6.61   1.93     1.08
> 4   10.23    6.55  17.89   5.34     3.67
> 5   18.37   28.32  69.43  22.15    15.98
> 
> I'm impressed!

Me, too, and kudos for the effort to produce those numbers. but still...

   It seems that Java compilers and virtual machines are
> already competitive with Common Lisp compilers.  I'll will have to
> look carefully at the Java code that was generated by the Linj
> compiler to see if there's something unfair going on.  Maybe someone
> can suggest another (similar) benchmark that has an easy proof of
> correctness and that I might try to convert to Java.

...CMIIAW, but is it not true that the Boyer benchmark involves only 
types which would be Java (what's the term) built-ins? Let's get some 
real OO into the game. Perhaps a silly exercise would be to take boyer 
and create class wrappers for Number and Float with methods like add and 
multiply. I guess the class hierarchies should have some depth to best 
exercise the dynamic dispatch. Unless of course there is a nice OO 
benchmark out there (but mebbe some global editing of what you have now 
is actually easier).

kt

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Dave Fayram
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <38ff3d6c.0406231249.14d6a788@posting.google.com>
Kenny Tilton <·······@nyc.rr.com> wrote in message news:

> ...CMIIAW, but is it not true that the Boyer benchmark involves only 
> types which would be Java (what's the term) built-ins? Let's get some 
> real OO into the game. Perhaps a silly exercise would be to take boyer 
> and create class wrappers for Number and Float with methods like add and 
> multiply. I guess the class hierarchies should have some depth to best 
> exercise the dynamic dispatch. Unless of course there is a nice OO 
> benchmark out there (but mebbe some global editing of what you have now 
> is actually easier).
> 
> kt

Yeah, but CMUCL should be doing something similar. Besides, Java 1.5
will do all that boxing nonsense automatically and far more
efficiently, so it's going to be a non-issue before long. A better
question is why it does so well up to a point, then dies off. I'll
address that in a  different post.
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <871xk6nstt.fsf@evaluator.pt>
Kenny Tilton <·······@nyc.rr.com> writes:

> Antonio Menezes Leitao wrote:
>> Indeed.  I received a similar suggestion by email and I went for a new
>> run of tests.  I also tried other Common Lisp compilers.  Without
>> tuning the GC, I got:
>> N   CMUCL Allegro  CLISP  ClientVM  ServerVM
>> 0    0.07    0.40   0.13   0.04     0.05  1    0.61    0.27   0.83
>> 0.24     0.13
>> 2    1.80    0.74   2.32   0.62     0.39
>> 3    4.78    2.08   6.61   1.93     1.08
>> 4   10.23    6.55  17.89   5.34     3.67
>> 5   18.37   28.32  69.43  22.15    15.98
>> I'm impressed!
>
> Me, too, and kudos for the effort to produce those numbers. but still...
>
>    It seems that Java compilers and virtual machines are
>> already competitive with Common Lisp compilers.  I'll will have to
>> look carefully at the Java code that was generated by the Linj
>> compiler to see if there's something unfair going on.  Maybe someone
>> can suggest another (similar) benchmark that has an easy proof of
>> correctness and that I might try to convert to Java.
>
> ...CMIIAW, but is it not true that the Boyer benchmark involves only
> types which would be Java (what's the term) built-ins? 

Well, as I said, I minimized the changes to Lisp code to the absolute
minimum, and this causes several annoying effects in the resulting
Java code.  As you can see in the Java code I posted, there are two
important, non built-in, types, namely linj.Cons and linj.Symbol.
These are very simplistic implementations of the Lisp cons a symbol
datatypes and they haven't been optimized at all.  They were made
initially just to demonstrate that you could use Lisp style in Java
and they are toy implementations.  Moreover, there are also some extra
non built-in types such as linj.Function, linj.Predicate2 that are
used as base classes to some annonymous inner classes implementing the
Java equivalent of Common Lisp lambdas.  Finally, albeit less
important, even arithmetic operations in the Java code are being done
using reference types, via the linj.Bignum class (a toy implementation
of Common Lisp rationals).  This is evident when we look at the
translation from Common Lisp (eql x y) to Java:

(x == y) || ((x instanceof Number) && (y instanceof Number) && x.equals(y))

Even the Common Lisp form

(do (...
     (n n (1- n)))
    ((zerop n) ...))

becomes:

for (Object n0 = n;
     ! (((Bignum)n0).compareTo(Bignum.valueOf(0)) == 0);
     ..., n0 = ((Bignum)n0).subtract(Bignum.valueOf(1))) {
}

So, I think that the code is not taking advantage of Java built-ins.

One built-in type that is heavilly used, however, is the
java.util.Hashtable where symbols are stored.  This is the equivalent
to a Common Lisp package, so they are both built-in in the respective
languages.  Anyway, they are not accounted on the final benchmarks
because, in Common Lisp, the overhead is removed at load-time.  This
was what made me remove the setup operation (where most interns are
done) from the timings.  However, just to increase the unfairness of
the Java benchmarks, there are still a few interns being done on the
test function, as well as list constructions that, I believe, CMUCL
can optimize away.

> Let's get some real OO into the game. Perhaps a silly exercise would
> be to take boyer and create class wrappers for Number and Float with
> methods like add and multiply.

That's what is being done but the performance bottleneck is not on
numerical operations.

> I guess the class hierarchies should have some depth to best
> exercise the dynamic dispatch. Unless of course there is a nice OO
> benchmark out there (but mebbe some global editing of what you have
> now is actually easier).

If someone wants to make the boyer benchmark more object-oriented,
I'll try to find some time to translate it again to Linj.  Only single
dispatch and no fancy method combinations, please :-)

Thanks,

Ant�nio Leit�o.
From: szymon
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87pt7ql9j0.fsf@darkstar.example.net>
Antonio Menezes Leitao <··············@evaluator.pt> writes:


> N   CMUCL Allegro  CLISP  ClientVM  ServerVM
> 0    0.07    0.40   0.13   0.04     0.05  
> 1    0.61    0.27   0.83   0.24     0.13
> 2    1.80    0.74   2.32   0.62     0.39
> 3    4.78    2.08   6.61   1.93     1.08
> 4   10.23    6.55  17.89   5.34     3.67
> 5   18.37   28.32  69.43  22.15    15.98

from CLISP's "ANNOUNCE" file:

"CLISP compares well with other ANSI CL implementations wrt performance in
most areas, such as CLOS, I/O, lists, integer arithmetics (CLISP's bignum
performance is better than that of some other CL implementations).  The
worst performance CLISP exhibits in the area of floating point arithmetics.
                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
While showing nothing spectacularly bad and easily outperforming Java,
                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ =:-P
Perl, TCL and any Scheme interpreter, CLISP is slower than another
open-source CL implementation, CMU CL (http://www.cons.org/cmucl), which
outperforms C and FORTRAN.  If your code is heavily numeric, you might
prefer CMUCL, otherwise CLISP is a wise choice."

Regards.
From: Julian Stecklina
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <86659i41g3.fsf@goldenaxe.localnet>
Antonio Menezes Leitao <··············@evaluator.pt> writes:

> N   CMUCL Allegro  CLISP  ClientVM  ServerVM
> 0    0.07    0.40   0.13   0.04     0.05  
> 1    0.61    0.27   0.83   0.24     0.13
> 2    1.80    0.74   2.32   0.62     0.39
> 3    4.78    2.08   6.61   1.93     1.08
> 4   10.23    6.55  17.89   5.34     3.67
> 5   18.37   28.32  69.43  22.15    15.98

Only to demonstrate my complete lack of knowledge about current Java
technology: What is the difference between Client and Server VM? Why
is the Client VM slower?

Regards,
-- 
Julian Stecklina 

Signed and encrypted mail welcome.
Key-Server: pgp.mit.edu         Key-ID: 0xD65B2AB5
FA38 DCD3 00EC 97B8 6DD8  D7CC 35D8 8D0E D65B 2AB5

Any sufficiently complicated C or Fortran program
contains an ad hoc informally-specified bug-ridden
slow implementation of half of Common Lisp.
 - Greenspun's Tenth Rule of Programming
From: Pascal Costanza
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbd5ka$p2n$1@newsreader2.netcologne.de>
Julian Stecklina wrote:
> Antonio Menezes Leitao <··············@evaluator.pt> writes:
> 
>>N   CMUCL Allegro  CLISP  ClientVM  ServerVM
>>0    0.07    0.40   0.13   0.04     0.05  
>>1    0.61    0.27   0.83   0.24     0.13
>>2    1.80    0.74   2.32   0.62     0.39
>>3    4.78    2.08   6.61   1.93     1.08
>>4   10.23    6.55  17.89   5.34     3.67
>>5   18.37   28.32  69.43  22.15    15.98
> 
> Only to demonstrate my complete lack of knowledge about current Java
> technology: What is the difference between Client and Server VM? Why
> is the Client VM slower?

The Server VM is tuned towards long-running programs without UI/GUI 
interactions whereas the Client VM is tuned towards short-lived programs 
with GUIs. For example, the garbage collector in the client version 
tries not to interfere with GUI interactions so that there are no long 
recognizable pauses. This means that the client garbage collector is 
generally somewhat less efficient overall.

One of those two VMs waits longer before bytecode is actually compiled 
into machine code, but I don't remember anymore which one does what in 
this regard.

Java uses dynamic compilation which results in more opportunities to 
produce more efficient code. For example, it allows the VM to inline 
(virtual) methods as long as there are no overriding methods, and undo 
the optimization as soon as that assumption does not hold anymore. 
AFAICS, no Common Lisp compiler does this kind of sophisticated 
optimization.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Mark McConnell
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <d3aed052.0406231025.571c81a2@posting.google.com>
Antonio Menezes Leitao <··············@evaluator.pt> wrote in message news:<·················@evaluator.pt>...

> I must stress that no optimization what so ever was done on the Linj
> libraries needed for this example (namely the cons and the symbol
> classes).

Was any optimization done when you ran the code in CMUCL?  I'm wondering about
 (proclaim '(optimize speed))
Sorry to have to ask--I'm not familiar with the Boyer test.
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87659i816a.fsf@evaluator.pt>
···············@yahoo.com (Mark McConnell) writes:

> Antonio Menezes Leitao <··············@evaluator.pt> wrote in message news:<·················@evaluator.pt>...
>
>> I must stress that no optimization what so ever was done on the Linj
>> libraries needed for this example (namely the cons and the symbol
>> classes).
>
> Was any optimization done when you ran the code in CMUCL?  I'm wondering about
>  (proclaim '(optimize speed))
> Sorry to have to ask--I'm not familiar with the Boyer test.

No.  I should have mention that.  Sorry.
From: Mark McConnell
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <d3aed052.0406240624.270fe96@posting.google.com>
Antonio Menezes Leitao <··············@evaluator.pt> wrote in message news:<··············@evaluator.pt>...
> ···············@yahoo.com (Mark McConnell) writes:
> 
> > Antonio Menezes Leitao <··············@evaluator.pt> wrote in message news:<·················@evaluator.pt>...
> >
> >> I must stress that no optimization what so ever was done on the Linj
> >> libraries needed for this example (namely the cons and the symbol
> >> classes).
> >
> > Was any optimization done when you ran the code in CMUCL?  I'm wondering about
> >  (proclaim '(optimize speed))
> > Sorry to have to ask--I'm not familiar with the Boyer test.
> 
> No.  I should have mention that.  Sorry.

The question is how Lisp *at its best* performs against Java at its
best, isn't it?  So the Lisp version should contain

(proclaim '(optimize speed))

To make the contest fair, what is the corresponding thing to do for
Java?  I think the answer is, nothing.  [What follows are memories of
the Java One conference in 2000, admittedly a bit dated.]  When Java's
Hotspot compiler came out, people asked how to optimize with it. 
"Should we give the compiler the option -O3", questions like that. 
The answer seemed to be, "No, Hotspot is carefully tuned, the
developer shouldn't mess with its tuning."  Or people would recommend
comparing the Client and Server VMs, which has been done earlier in
this thread.

When you complile with (optimize speed) in CMU CL, you get lots of
information about where numbers are boxed, so you can decide whether
to put in
(the fixnum ...) declarations.
From: Mark McConnell
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <d3aed052.0406280706.601eb9c3@posting.google.com>
···············@yahoo.com (Mark McConnell) wrote in message news:<···························@posting.google.com>...
> Antonio Menezes Leitao <··············@evaluator.pt> wrote in message news:<··············@evaluator.pt>...
> > ···············@yahoo.com (Mark McConnell) writes:
> > 
> > > Antonio Menezes Leitao <··············@evaluator.pt> wrote in message news:<·················@evaluator.pt>...
> > >
> > >> I must stress that no optimization what so ever was done on the Linj
> > >> libraries needed for this example (namely the cons and the symbol
> > >> classes).
> > >
> > > Was any optimization done when you ran the code in CMUCL?  I'm wondering about
> > >  (proclaim '(optimize speed))
> > > Sorry to have to ask--I'm not familiar with the Boyer test.
> > 
> > No.  I should have mention that.  Sorry.
> 
> The question is how Lisp *at its best* performs against Java at its
> best, isn't it?  So the Lisp version should contain
> 
> (proclaim '(optimize speed))
> 
> To make the contest fair, what is the corresponding thing to do for
> Java?  I think the answer is, nothing.  [What follows are memories of
> the Java One conference in 2000, admittedly a bit dated.]  When Java's
> Hotspot compiler came out, people asked how to optimize with it. 
> "Should we give the compiler the option -O3", questions like that. 
> The answer seemed to be, "No, Hotspot is carefully tuned, the
> developer shouldn't mess with its tuning."

To clarify: I'm concerned the test was unfair to Lisp.  Java's
compiler tries to optimize for speed, but Lisp won't try [or won't try
its hardest] unless you say (proclaim '(optimize speed)).  Antonio, is
there a chance you could run the test again with that line included?
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87y8m7zib2.fsf@evaluator.pt>
···············@yahoo.com (Mark McConnell) writes:

> To clarify: I'm concerned the test was unfair to Lisp.  Java's
> compiler tries to optimize for speed, but Lisp won't try [or won't try
> its hardest] unless you say (proclaim '(optimize speed)).  Antonio, is
> there a chance you could run the test again with that line included?

Sure.  I added a 

(declaim (optimize (speed 3) (safety 0) (debug 0) (compilation-speed 0)))

at the beginning of the (Common Lisp) file, recompiled it and timed it
again.  Here are the results of two runs (I also run the Java code
again):

N  CMUCL  CLISP Allegro ServerVM
0   0.04   0.14   0.02   0.05
1   0.12   0.84   0.18   0.13
2   0.37   2.40   0.51   0.43
3   1.18   6.28   1.46   1.11
4   2.94  18.24   5.30   3.68
5  11.81  69.04  24.04  15.81

N  CMUCL  CLISP Allegro ServerVM
0   0.02   0.13   0.03   0.02
1   0.17   0.84   0.18   0.13
2   0.40   2.32   0.51   0.40
3   1.02   6.57   1.45   1.08
4   3.03  17.99   4.82   3.71
5  13.03  70.86  23.35  15.37

The results are not very different from the previous ones I published
and that I repeat below:

N  CMUCL  CLISP Allegro ServerVM
0   0.04   0.13   0.04   0.02
1   0.13   0.84   0.26   0.18
2   0.41   2.31   0.72   0.50
3   1.25   6.58   1.99   1.46
4   3.22  17.87   6.36   3.89
5  12.60  69.65  26.97  19.25

I guess the Boyer benchmark doesn't show much opportunity for
optimization.

One last note:

I think we shouldn't put too much confidence in these numbers.  My
test machine is one of those new Centrinos that dynamically adjusts
the processor speed.  This might cause inconsistent timings.  One
strange phenomena is the larger variance of the JVM compared with the
Lisps.  In the same Common Lisp environment I get (more or less)
consistent timings, but in the JVM I get from 15 s to 25 s for the
last test case (apparently, depending on the day of the test :-).

Anyway, given the investment being done in Java compared with the
investment being done in Common Lisp, I foresee difficult times for
Common Lisp compilers that want to compete with Java for speed.
Fortunately, speed is the least of my concerns.  Usually, all my code
is compiled with (declaim (optimize (speed 0) (safety 3) (debug 3))).

Best regards,

Ant�nio Leit�o.
From: Mark McConnell
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <d3aed052.0406290816.415d95e2@posting.google.com>
Antonio Menezes Leitao <··············@evaluator.pt> wrote in message news:<··············@evaluator.pt>...
> ···············@yahoo.com (Mark McConnell) writes:
> 
> > To clarify: I'm concerned the test was unfair to Lisp.  Java's
> > compiler tries to optimize for speed, but Lisp won't try [or won't try
> > its hardest] unless you say (proclaim '(optimize speed)).  Antonio, is
> > there a chance you could run the test again with that line included?
> 
> Sure.  I added a 
> 
> (declaim (optimize (speed 3) (safety 0) (debug 0) (compilation-speed 0)))
> 
> at the beginning of the (Common Lisp) file, recompiled it and timed it
> again.  Here are the results of two runs (I also run the Java code
> again):
> 
> N  CMUCL  CLISP Allegro ServerVM
> 0   0.04   0.14   0.02   0.05
> 1   0.12   0.84   0.18   0.13
> 2   0.37   2.40   0.51   0.43
> 3   1.18   6.28   1.46   1.11
> 4   2.94  18.24   5.30   3.68
> 5  11.81  69.04  24.04  15.81
> 
> N  CMUCL  CLISP Allegro ServerVM
> 0   0.02   0.13   0.03   0.02
> 1   0.17   0.84   0.18   0.13
> 2   0.40   2.32   0.51   0.40
> 3   1.02   6.57   1.45   1.08
> 4   3.03  17.99   4.82   3.71
> 5  13.03  70.86  23.35  15.37
> 
> The results are not very different from the previous ones I published
> and that I repeat below:
> 
> N  CMUCL  CLISP Allegro ServerVM
> 0   0.04   0.13   0.04   0.02
> 1   0.13   0.84   0.26   0.18
> 2   0.41   2.31   0.72   0.50
> 3   1.25   6.58   1.99   1.46
> 4   3.22  17.87   6.36   3.89
> 5  12.60  69.65  26.97  19.25
> 
> I guess the Boyer benchmark doesn't show much opportunity for
> optimization.
> 
> One last note:
> 
> I think we shouldn't put too much confidence in these numbers.  My
> test machine is one of those new Centrinos that dynamically adjusts
> the processor speed.  This might cause inconsistent timings.

Thanks for the extra testing.  The result still makes me sad, though
you point out we shouldn't put too much confidence in it.  Did the
CMUCL compiler issue any notes or warnings during compilation?
From: rif
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <wj0659anx5o.fsf@five-percent-nation.mit.edu>
> Thanks for the extra testing.  The result still makes me sad, though
> you point out we shouldn't put too much confidence in it.  Did the
> CMUCL compiler issue any notes or warnings during compilation?

Yeah, this is REALLY critical.  I find that CMUCL is easy to write
slow programs with, but usually with a bit of work, you can come up
with a program that's much faster.  Generally I find I can get to
within about 25% of C with a moderate amount of work.  I've never
personally compared to java.  Was it stated earlier in the thread how
fast the C++ version was?  If the java and the C++ are quite close,
then I'd guess that the CL version's already fairly lean.  If the C++
is much faster, then you could probably sweat the CL version downn a
bit.

rif
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <871xjyktmt.fsf@evaluator.pt>
···············@yahoo.com (Mark McConnell) writes:

> Antonio Menezes Leitao <··············@evaluator.pt> wrote in message news:<··············@evaluator.pt>...
>> ···············@yahoo.com (Mark McConnell) writes:
>> 
>> > To clarify: I'm concerned the test was unfair to Lisp.  Java's
>> > compiler tries to optimize for speed, but Lisp won't try [or won't try
>> > its hardest] unless you say (proclaim '(optimize speed)).  Antonio, is
>> > there a chance you could run the test again with that line included?
>> 
>> Sure.  I added a 
>> 
>> (declaim (optimize (speed 3) (safety 0) (debug 0) (compilation-speed 0)))
>> 
>> at the beginning of the (Common Lisp) file, recompiled it and timed it
>> again.  Here are the results of two runs (I also run the Java code
>> again):
>> 
>> N  CMUCL  CLISP Allegro ServerVM
>> 0   0.04   0.14   0.02   0.05
>> 1   0.12   0.84   0.18   0.13
>> 2   0.37   2.40   0.51   0.43
>> 3   1.18   6.28   1.46   1.11
>> 4   2.94  18.24   5.30   3.68
>> 5  11.81  69.04  24.04  15.81
>> 
>> N  CMUCL  CLISP Allegro ServerVM
>> 0   0.02   0.13   0.03   0.02
>> 1   0.17   0.84   0.18   0.13
>> 2   0.40   2.32   0.51   0.40
>> 3   1.02   6.57   1.45   1.08
>> 4   3.03  17.99   4.82   3.71
>> 5  13.03  70.86  23.35  15.37
>> 
>> The results are not very different from the previous ones I published
>> and that I repeat below:
>> 
>> N  CMUCL  CLISP Allegro ServerVM
>> 0   0.04   0.13   0.04   0.02
>> 1   0.13   0.84   0.26   0.18
>> 2   0.41   2.31   0.72   0.50
>> 3   1.25   6.58   1.99   1.46
>> 4   3.22  17.87   6.36   3.89
>> 5  12.60  69.65  26.97  19.25
>> 
>> I guess the Boyer benchmark doesn't show much opportunity for
>> optimization.
>> 
>> One last note:
>> 
>> I think we shouldn't put too much confidence in these numbers.  My
>> test machine is one of those new Centrinos that dynamically adjusts
>> the processor speed.  This might cause inconsistent timings.
>
> Thanks for the extra testing.  The result still makes me sad, though
> you point out we shouldn't put too much confidence in it.  Did the
> CMUCL compiler issue any notes or warnings during compilation?

Yes.  Here they are

; Python version 1.1, VM version Intel x86 on 29 JUN 04 08:40:12 pm.
; Compiling: /home/aml/evaluator/tools/Linj/tests/boyer.lisp 29 JUN 04 08:39:54 pm
; 
; 
; File: /home/aml/evaluator/tools/Linj/tests/boyer.lisp

; In: DEFUN TEST

;   (ZEROP N)
; ==>
;   (= N 0)
; Note: Unable to optimize due to type uncertainty:
;     The first argument is a NUMBER, not a FLOAT.
; 
; Note: Unable to optimize due to type uncertainty:
;     The first argument is a NUMBER, not a (COMPLEX SINGLE-FLOAT).
; 
; Note: Unable to optimize due to type uncertainty:
;     The first argument is a NUMBER, not a (COMPLEX DOUBLE-FLOAT).
; 
; Note: Unable to open code because:
;     Operands might not be the same type.
; 
;   (1- N)
; ==>
;   (- N 1)
; Note: Unable to optimize due to type uncertainty:
;     The first argument is a NUMBER, not a FLOAT.
; 
; Note: Unable to optimize due to type uncertainty:
;     The first argument is a NUMBER, not a (COMPLEX SINGLE-FLOAT).
; 
; Note: Unable to optimize due to type uncertainty:
;     The first argument is a NUMBER, not a (COMPLEX DOUBLE-FLOAT).
; 
; Note: Forced to do GENERIC-- (cost 10).
;     Unable to do inline fixnum arithmetic (cost 1) because:
;     The first argument is a NUMBER, not a FIXNUM.
;     The result is a NUMBER, not a FIXNUM.
;     Unable to do inline fixnum arithmetic (cost 2) because:
;     The first argument is a NUMBER, not a FIXNUM.
;     The result is a NUMBER, not a FIXNUM.
;     etc.
; 

; In: DEFUN APPLY-SUBST

;   (ASSOC TERM ALIST)
; Note: Unable to convert to EQ test because:
;     Item might be a number
; 

; In: DEFUN REWRITE

;   (INCF *REWRITE-COUNT*)
; --> LET* 
; ==>
;   (+ *REWRITE-COUNT* 1)
; Note: Unable to optimize due to type uncertainty:
;     The first argument is a NUMBER, not a FLOAT.
; 
; Note: Unable to optimize due to type uncertainty:
;     The first argument is a NUMBER, not a (COMPLEX SINGLE-FLOAT).
; 
; Note: Unable to optimize due to type uncertainty:
;     The first argument is a NUMBER, not a (COMPLEX DOUBLE-FLOAT).
; 
; Note: Forced to do GENERIC-+ (cost 10).
;     Unable to do inline fixnum arithmetic (cost 1) because:
;     The first argument is a NUMBER, not a FIXNUM.
;     The result is a NUMBER, not a FIXNUM.
;     Unable to do inline fixnum arithmetic (cost 2) because:
;     The first argument is a NUMBER, not a FIXNUM.
;     The result is a NUMBER, not a FIXNUM.
;     etc.
; 

; In: DEFUN ONE-WAY-UNIFY1

;   (ASSOC TERM2 UNIFY-SUBST)
; Note: Unable to convert to EQ test because:
;     Item might be a number
; 
;   (EQL TERM1 TERM2)
; Note: Unable to optimize due to type uncertainty:
;     The first argument is a T, not a SINGLE-FLOAT.
;     The second argument is a NUMBER, not a SINGLE-FLOAT.
; 
; Note: Unable to optimize due to type uncertainty:
;     The first argument is a T, not a DOUBLE-FLOAT.
;     The second argument is a NUMBER, not a DOUBLE-FLOAT.
; 
; Note: Forced to do GENERIC-EQL (cost 10).
;     Unable to do inline fixnum comparison (cost 4) because:
;     The first argument is a T, not a FIXNUM.
;     The second argument is a NUMBER, not a FIXNUM.
; 

; In: DEFUN TERM-EQUAL?

;   (EQL X Y)
; Note: Unable to optimize due to type uncertainty:
;     The first argument is a T, not a SINGLE-FLOAT.
;     The second argument is a T, not a SINGLE-FLOAT.
; 
; Note: Unable to optimize due to type uncertainty:
;     The first argument is a T, not a DOUBLE-FLOAT.
;     The second argument is a T, not a DOUBLE-FLOAT.
; 
; Note: Forced to do GENERIC-EQL (cost 10).
;     Unable to do inline fixnum comparison (cost 4) because:
;     The first argument is a T, not a FIXNUM.
;     The second argument is a T, not a FIXNUM.
; 


As far as I can see, there's some room for optimization in the 
;   (INCF *REWRITE-COUNT*)
case.

I experimented to rewrite it as   
(the fixnum (incf (the fixnum *rewrite-count*))) 
because it was a bit unfair for the Common Lisp side to use generic
arithmetic while Java was using ints but, in fact, it doesn't show any
improvement (in any of the Common Lisp implementations).  In fact,
looking at a flat profile in Allegro, what shows up at the top is just 
function invocation for rewrite-args, rewrite and rewrite-lemmas.

I think we should move on to another benchmark.  In this one, at least
CMUCL shows that Common Lisp programs can run faster than a Java
program so it's not an entirely bad result.

Ant�nio Leit�o.
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbssot$r17$1@ulric.tng.de>
Have you also tried the "tiger", Java 1.5?


Andr�
--
From: Joe Marshall
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <n02l2f4q.fsf@ccs.neu.edu>
Antonio Menezes Leitao <··············@evaluator.pt> writes:

> ; Python version 1.1, VM version Intel x86 on 29 JUN 04 08:40:12 pm.
> ; Compiling: /home/aml/evaluator/tools/Linj/tests/boyer.lisp 29 JUN 04 08:39:54 pm
> ; 
> ; 
> ; File: /home/aml/evaluator/tools/Linj/tests/boyer.lisp
>
> ; In: DEFUN TEST
>
> ;   (ZEROP N)
> ;   (1- N)

These won't make a difference, we're only counting as high as 5.

> ; In: DEFUN APPLY-SUBST
>
> ;   (ASSOC TERM ALIST)
> ; Note: Unable to convert to EQ test because:
> ;     Item might be a number
> ; 

Can't be fixed.

> ; In: DEFUN REWRITE
>
> ;   (INCF *REWRITE-COUNT*)
> ; --> LET* 
> ; ==>
> ;   (+ *REWRITE-COUNT* 1)

Unlikely to be an issue.

> ; In: DEFUN ONE-WAY-UNIFY1
>
> ;   (ASSOC TERM2 UNIFY-SUBST)
> ; Note: Unable to convert to EQ test because:
> ;     Item might be a number

Can't be fixed.

> ;   (EQL TERM1 TERM2)
> ; Note: Unable to optimize due to type uncertainty:
> ;     The first argument is a T, not a SINGLE-FLOAT.
> ;     The second argument is a NUMBER, not a SINGLE-FLOAT.
> ; 
> ; Note: Unable to optimize due to type uncertainty:
> ;     The first argument is a T, not a DOUBLE-FLOAT.
> ;     The second argument is a NUMBER, not a DOUBLE-FLOAT.
> ; 
> ; Note: Forced to do GENERIC-EQL (cost 10).
> ;     Unable to do inline fixnum comparison (cost 4) because:
> ;     The first argument is a T, not a FIXNUM.
> ;     The second argument is a NUMBER, not a FIXNUM.

This one might be improved slightly since it is known that TERM2 is
NUMBERP.  Perhaps something like this:

(defmacro fixnump (thing)
  `(typep ,thing 'fixnum))

Replace this code:
                 ((numberp term2)       ; This bug fix makes
                  (equal term1 term2)) ; nboyer 10-25% slower!

With this:
                 ((fixnump term2) (and (fixnump term1)
                                       (= (the fixnum term1)
                                          (the fixnum term2))))
                 ((numberp term2) (and (numberp term1)
                                       (= (the number term1)
                                          (the number term2))))

This should inline the fixnum case, and I don't think that the other
numbers are of interest.  You could probably take out the number
clause, but that wouldn't quite be the same.

> ; In: DEFUN TERM-EQUAL?
>
> ;   (EQL X Y)
> ; Note: Unable to optimize due to type uncertainty:
> ;     The first argument is a T, not a SINGLE-FLOAT.
> ;     The second argument is a T, not a SINGLE-FLOAT.
> ; 
> ; Note: Unable to optimize due to type uncertainty:
> ;     The first argument is a T, not a DOUBLE-FLOAT.
> ;     The second argument is a T, not a DOUBLE-FLOAT.
> ; 
> ; Note: Forced to do GENERIC-EQL (cost 10).
> ;     Unable to do inline fixnum comparison (cost 4) because:
> ;     The first argument is a T, not a FIXNUM.
> ;     The second argument is a T, not a FIXNUM.

This might be improved slightly, but there is the question of what to
do about that eql clause.  If fixnums are EQ comparable and there are
no floats or bignums, you can omit the clause. 

(defun term-equal? (x y)
  (or (eq x y)
      (and (consp x)
           (consp y)
           (eq (car x) (car y))
           (term-args-equal? (cdr x) (cdr y)))
      (eql x y)))

(defun term-args-equal? (list1 list2)
  (or (eq list1 list2)
      (and (consp list1)
           (consp list2)
           (term-equal? (car list1) (car list2))
           (term-args-equal? (cdr list1) (cdr list2)))))

> As far as I can see, there's some room for optimization in the 
> ;   (INCF *REWRITE-COUNT*)
> case.

Yes, but it isn't likely to make a difference.

> I experimented to rewrite it as   
> (the fixnum (incf (the fixnum *rewrite-count*))) 
> because it was a bit unfair for the Common Lisp side to use generic
> arithmetic while Java was using ints but, in fact, it doesn't show any
> improvement (in any of the Common Lisp implementations).  In fact,
> looking at a flat profile in Allegro, what shows up at the top is just 
> function invocation for rewrite-args, rewrite and rewrite-lemmas.

I don't see much that can be done with these, but you could inline
REWRITE.
From: Juho Snellman
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <slrnce5s49.6md.jsnell@melkinpaasi.cs.Helsinki.FI>
<···@ccs.neu.edu> wrote:
>Antonio Menezes Leitao <··············@evaluator.pt> writes:
>> I experimented to rewrite it as   
>> (the fixnum (incf (the fixnum *rewrite-count*))) 
>> because it was a bit unfair for the Common Lisp side to use generic
>> arithmetic while Java was using ints but, in fact, it doesn't show any
>> improvement (in any of the Common Lisp implementations).  In fact,
>> looking at a flat profile in Allegro, what shows up at the top is just 
>> function invocation for rewrite-args, rewrite and rewrite-lemmas.
>
>I don't see much that can be done with these, but you could inline
>REWRITE.

Depends on what sort of changes we're allowed to make to the
benchmark. For example, rewriting REWRITE by moving the mutally
recursive helpers from toplevel functions to locals allows SBCL (and
probably CMUCL) to optimize it better.

Something like this:

(defun rewrite (term)
  (labels ((rewrite-args (list)
              (if (null list)
                 '()
                 (scons (rewrite (car list))
                        (rewrite-args (cdr list))
                        list)))
            (rewrite-with-lemmas (term list)
               (cond ((null list) term)
                     ((one-way-unify term (cadr (car list)))
                      (rewrite (apply-subst unify-subst (caddr (car list)))$
                     (t (rewrite-with-lemmas term (cdr list)))))
            (rewrite-aux (term)
               (incf *rewrite-count*)
               (if (not (consp term))
                   term
                   (rewrite-with-lemmas (scons (car term)
                                               (rewrite-args (cdr term))
                                               term)
                                        (get (car term) 'lemmas)))))
     (rewrite-aux term)))

-- 
Juho Snellman
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87u0wtdkl4.fsf@evaluator.pt>
······@iki.fi (Juho Snellman) writes:

> <···@ccs.neu.edu> wrote:
>>Antonio Menezes Leitao <··············@evaluator.pt> writes:
>>> I experimented to rewrite it as   
>>> (the fixnum (incf (the fixnum *rewrite-count*))) 
>>> because it was a bit unfair for the Common Lisp side to use generic
>>> arithmetic while Java was using ints but, in fact, it doesn't show any
>>> improvement (in any of the Common Lisp implementations).  In fact,
>>> looking at a flat profile in Allegro, what shows up at the top is just 
>>> function invocation for rewrite-args, rewrite and rewrite-lemmas.
>>
>>I don't see much that can be done with these, but you could inline
>>REWRITE.
>
> Depends on what sort of changes we're allowed to make to the
> benchmark. For example, rewriting REWRITE by moving the mutally
> recursive helpers from toplevel functions to locals allows SBCL (and
> probably CMUCL) to optimize it better.
> ...

It seems to me that all the suggested changes that improve the Common
Lisp version will also improve the Java version.

I really think we should move on to a different benchmark.

Ant�nio Leit�o.
From: Juho Snellman
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <slrnce6423.iqo.jsnell@melkinpaasi.cs.Helsinki.FI>
<··············@evaluator.pt> wrote:
>······@iki.fi (Juho Snellman) writes:
>>>I don't see much that can be done with these, but you could inline 
>>>REWRITE.              
>>
>> For example, rewriting REWRITE by moving the mutally
>> recursive helpers from toplevel functions to locals allows SBCL (and
>> probably CMUCL) to optimize it better.
>> ...
>
>It seems to me that all the suggested changes that improve the Common
>Lisp version will also improve the Java version.

It wasn't my intent to suggest that benchmark should be changed.
Adding declarations is one thing, rewriting parts of a 20 year old (?)
benchmark is quite another. I was just pointing out that there
actually was something that could be done to REWRITE to make it more
efficient, at least if targeting a specific implementation.

However, you could wrong about the change also improving the Java
version. I'd be suprised if the JIT didn't already do the equivalent
optimization by itself.

>I really think we should move on to a different benchmark.

Eric Marsden's cl-bench contains some benchmarks that are more
interesting than calculating (fib bignum). You could try DEFLATE or
RICHARDS.

<http://www.chez.com/emarsden/downloads/cl-bench.tar.gz>

-- 
Juho Snellman
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87r7ru6hi4.fsf@evaluator.pt>
······@iki.fi (Juho Snellman) writes:

> <··············@evaluator.pt> wrote:
>
>>I really think we should move on to a different benchmark.
>
> Eric Marsden's cl-bench contains some benchmarks that are more
> interesting than calculating (fib bignum). You could try DEFLATE or
> RICHARDS.
>

I tried RICHARDS.  This required a lot more type declarations than
boyer because it uses several defstructs and Linj cannot resolve
accessors without type information about the arguments.  (In the boyer
benchmark, the most used datatype was the list and Linj knows about
list operators).

Here are the changes (with some comments):

36a37,41
> (defun main (n/int)
>   (let ((start (in (the system) (current-time-millis))))
>     (richards n)
>     (let ((end (in (the system) (current-time-millis))))
>       (format t "time: ~A~%" (/ (- end start) 1000.0)))))

Added a timing function.

38c43
< (eval-when (:compile-toplevel :load-toplevel :execute)
---
> ;;(eval-when (:compile-toplevel :load-toplevel :execute)

Linj doesn't have eval-when.

45,46c50,51
<   (defconstant noWork nil)
<   (defconstant noTask nil)
---
>   (defconstant noWork (the packet null))
>   (defconstant noTask (the taskControlBlock null))

The nil value is a boolean.  Changed to a correctly typed null.

48c53
<   (defconstant workPacketKind 2))
---
>   (defconstant workPacketKind 2);;)

The ) is from the eval-when

51,52c56,57
< (defvar currentTask nil)
< (defvar currentTaskIdentity nil)
---
> (defvar currentTask (the taskControlBlock null))
> (defvar currentTaskIdentity -1L)

Again, nil is not adequate.

54c59
< (declaim (simple-vector taskTable))
---
> ;;(declaim (simple-vector taskTable))
59c64
< (declaim (fixnum layout queuePacketCount holdCount))
---
> ;;(declaim (fixnum layout queuePacketCount holdCount))
61,66c66,73
< (declaim (inline make-taskControlBlock make-packet make-deviceTaskDataRecord
< 		 make-handlerTaskDataRecord make-idleTaskDataRecord
< 		 make-workerTaskDataRecord wait))
< 
< (defstruct (taskControlBlock (:constructor make-taskControlBLock ()))
<   packetPending taskWaiting taskHolding link identity
---
> ;; (declaim (inline make-taskControlBlock make-packet make-deviceTaskDataRecord
> ;; 		 make-handlerTaskDataRecord make-idleTaskDataRecord
> ;; 		 make-workerTaskDataRecord wait))
> 
> (defstruct (taskControlBlock (:constructor make-taskControlBlock ()))
>   packetPending
>   (taskWaiting nil)
>   taskHolding link identity

Linj doesn't implement declaim.  Added boolean default to the
taskWaiting slot.  Corrected name of the constructor.


74c81
<   (data '#() :type simple-vector))
---
>   (data (make-array 0 :element-type 'fixnum)))

Added explicit type for array elements.

80c87,88
<   workIn deviceIn)
---
>   (workIn null :type packet)
>   (deviceIn null :type packet))

Added type for slots

90c98
< (defun wait ()
---
> (defun task-wait ()

Changed name to avoid conflicts with Java's wait.

101c109
< (defun deviceTaskDataRecord-run (self work)
---
> (defun deviceTaskDataRecord-run (self/deviceTaskDataRecord work/packet)

Added type declarations.

107c115
< 	     (wait)
---
> 	     (task-wait)
113c121
<        (if tracing (trace-it (packet-datum functionWork)))
---
>        (when tracing (trace-it (packet-datum functionWork)))

In Linj, if requires three arguments.

116,118c124,125
< (defun handlerTaskDataRecord-run (self work)
<   (if (eq noWork work)
<       nil
---
> (defun handlerTaskDataRecord-run (self/handlerTaskDataRecord work/packet)
>   (unless (eq noWork work)

Idem.

124c131
< 	(wait)
---
> 	(task-wait)
133c140
< 		(wait)
---
> 		(task-wait)
142c149
< (defun idleTaskDataRecord-run (self work)
---
> (defun idleTaskDataRecord-run (self/idleTaskDataRecord work)
159c166
< (defun workerTaskDataRecord-run (self work)
---
> (defun workerTaskDataRecord-run (self/workerTaskDataRecord work/packet)
161c168
<       (wait)
---
>       (task-wait)
170c177
< 	 ((> i 3) nil)
---
> 	 ((> i 3))

Don't want to return nil yet.

174,175c181,182
< 	 (if (> (workerTaskDataRecord-count self) 256)
< 	     (setf (workerTaskDataRecord-count self) 1))
---
> 	 (when (> (workerTaskDataRecord-count self) 256)
> 	   (setf (workerTaskDataRecord-count self) 1))
182c189
< (defun appendHead (packet queueHead)
---
> (defun appendHead (packet/packet queueHead/packet)
189,191c196,198
< 	    ((eq noWork link) nil)
< 	    (setq mouse link)
< 	    (setq link (packet-link mouse)))
---
> 	    ((eq noWork link))
> 	  (setq mouse link)
> 	  (setq link (packet-link mouse)))
197,198c204,205
<   (setq currentTask nil)
<   (setq currentTaskIdentity nil)
---
>   (setq currentTask null)
>   (setq currentTaskIdentity -1L)
208,209c215
<   (let ((workQ))
<     (setq workQ (createPacket noWork worker workPacketKind))
---
>   (let ((workQ (createPacket noWork worker workPacketKind)))

Make it easy for type inference.

236c242
< 	 (if tracing (trace-it currentTaskIdentity))
---
> 	 (when tracing (trace-it currentTaskIdentity))
242c248
<     (if (eq noTask tk) (error "findTask failed"))
---
>     (when (eq noTask tk) (error "findTask failed"))
250c256
< (defun queuePacket (packet)
---
> (defun queuePacket (packet/packet)
273,276c279,281
<   (if (>= 0 layout)
<       (progn
<        (format t "~%")
<        (setq layout 30)))
---
>   (when (>= 0 layout)
>     (format t "~%")
>     (setq layout 30))
301,302c306,307
< (defun createPacket (link identity kind)
<   (create-packet link identity kind))
---
> ;; (defun createPacket (link identity kind)
> ;;   (create-packet link identity kind))

Linj already treats create-packet and createPacket as the same name.

304c309
< (defun running (tcb)
---
> (defun running (tcb/taskControlBlock)
324c329
< (defun isTaskHoldingOrWaiting (tcb)
---
> (defun isTaskHoldingOrWaiting (tcb/taskControlBlock)
329c334
< (defun isWaitingWithPacket (tcb)
---
> (defun isWaitingWithPacket (tcb/taskControlBlock)
334c339
< (defun packetNowPending (tcb)
---
> (defun packetNowPending (tcb/taskControlBlock)
340,341c345
< (defun create-taskControlBlock
<   (link identity priority initialWorkQueue initialState privateData)
---
> (defun create-taskControlBlock (link identity priority initialWorkQueue initialState/taskControlBlock privateData)
357c361
< (defun addInput (tcb packet oldTask)
---
> (defun addInput (tcb/taskControlBlock packet oldTask/taskControlBlock)
371,372c375,376
< (defun runTask (tcb)
<   (let ((message nil))
---
> (defun runTask (tcb/taskControlBlock)
>   (let ((message (the packet null)))
384,388c388,392
<   (typecase self
< 	    (deviceTaskDataRecord (deviceTaskDataRecord-run self work))
< 	    (handlerTaskDataRecord (handlerTaskDataRecord-run self work))
< 	    (idleTaskDataRecord (idleTaskDataRecord-run self work))
< 	    (workerTaskDataRecord (workerTaskDataRecord-run self work))))
---
>   (etypecase self
>     (deviceTaskDataRecord (deviceTaskDataRecord-run self work))
>     (handlerTaskDataRecord (handlerTaskDataRecord-run self work))
>     (idleTaskDataRecord (idleTaskDataRecord-run self work))
>     (workerTaskDataRecord (workerTaskDataRecord-run self work))))

Typecase changed to etypecase so that all control flow paths wither
return a value or abort.


390c394
< (defun create-packet (link identity kind)
---
> (defun create-packet (link identity kind/long)
396c400
<     (let ((v (make-array 4 :initial-element 0)))
---
>     (let ((v (make-array 4 :element-type 'fixnum :initial-element 0)))
411c415
< (defun deviceInAdd (tk packet)
---
> (defun deviceInAdd (tk/handlerTaskDataRecord packet/packet)
416c420
< (defun workInAdd (tk packet)
---
> (defun workInAdd (tk/handlerTaskDataRecord packet/packet)


And now, the results:

              CMUCL       Allegro        Java
Iterations noopt  opt   noopt  opt   client server
  1000000   0.5   0.3    2.3   1.2    0.5     1.6
  5000000   2.6   1.6    8.9   5.7    1.5     2.2
 25000000   9.7   6.4   24.6  13.7    6.3     4.9
125000000  28.8  18.4  100.9  58.6   16.5    12.5

The noopt means just the normal defaults for optimization.
The opt means that a 

(declaim (optimize (speed 3) (safety 0) (debug 0) (compilation-speed 0)))

was added in the beginning of the file.

Once again, I'm impressed.  And surprised with Allegro performance.
I didn't include results for CLISP because I didn't look to me it
couldn't improve the situation.

Comments?
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87lli26f72.fsf@evaluator.pt>
······@iki.fi (Juho Snellman) writes:

> <··············@evaluator.pt> wrote:
>
>>I really think we should move on to a different benchmark.
>
> Eric Marsden's cl-bench contains some benchmarks that are more
> interesting than calculating (fib bignum). You could try DEFLATE or
> RICHARDS.
>

I tried RICHARDS.  This required a lot more type declarations than
boyer because it uses several defstructs and Linj cannot resolve
accessors without type information about the arguments.  (In the boyer
benchmark, the most used datatype was the list and Linj knows about
list operators).

Here are the changes (with some comments):

36a37,41
> (defun main (n/int)
>   (let ((start (in (the system) (current-time-millis))))
>     (richards n)
>     (let ((end (in (the system) (current-time-millis))))
>       (format t "time: ~A~%" (/ (- end start) 1000.0)))))

Added a timing function.

38c43
< (eval-when (:compile-toplevel :load-toplevel :execute)
---
> ;;(eval-when (:compile-toplevel :load-toplevel :execute)

Linj doesn't have eval-when.

45,46c50,51
<   (defconstant noWork nil)
<   (defconstant noTask nil)
---
>   (defconstant noWork (the packet null))
>   (defconstant noTask (the taskControlBlock null))

The nil value is a boolean.  Changed to a correctly typed null.

48c53
<   (defconstant workPacketKind 2))
---
>   (defconstant workPacketKind 2);;)

The ) is from the eval-when

51,52c56,57
< (defvar currentTask nil)
< (defvar currentTaskIdentity nil)
---
> (defvar currentTask (the taskControlBlock null))
> (defvar currentTaskIdentity -1L)

Again, nil is not adequate.

54c59
< (declaim (simple-vector taskTable))
---
> ;;(declaim (simple-vector taskTable))
59c64
< (declaim (fixnum layout queuePacketCount holdCount))
---
> ;;(declaim (fixnum layout queuePacketCount holdCount))
61,66c66,73
< (declaim (inline make-taskControlBlock make-packet make-deviceTaskDataRecord
< 		 make-handlerTaskDataRecord make-idleTaskDataRecord
< 		 make-workerTaskDataRecord wait))
< 
< (defstruct (taskControlBlock (:constructor make-taskControlBLock ()))
<   packetPending taskWaiting taskHolding link identity
---
> ;; (declaim (inline make-taskControlBlock make-packet make-deviceTaskDataRecord
> ;; 		 make-handlerTaskDataRecord make-idleTaskDataRecord
> ;; 		 make-workerTaskDataRecord wait))
> 
> (defstruct (taskControlBlock (:constructor make-taskControlBlock ()))
>   packetPending
>   (taskWaiting nil)
>   taskHolding link identity

Linj doesn't implement declaim.  Added boolean default to the
taskWaiting slot.  Corrected name of the constructor.


74c81
<   (data '#() :type simple-vector))
---
>   (data (make-array 0 :element-type 'fixnum)))

Added explicit type for array elements.

80c87,88
<   workIn deviceIn)
---
>   (workIn null :type packet)
>   (deviceIn null :type packet))

Added type for slots

90c98
< (defun wait ()
---
> (defun task-wait ()

Changed name to avoid conflicts with Java's wait.

101c109
< (defun deviceTaskDataRecord-run (self work)
---
> (defun deviceTaskDataRecord-run (self/deviceTaskDataRecord work/packet)

Added type declarations.

107c115
< 	     (wait)
---
> 	     (task-wait)
113c121
<        (if tracing (trace-it (packet-datum functionWork)))
---
>        (when tracing (trace-it (packet-datum functionWork)))

In Linj, if requires three arguments.

116,118c124,125
< (defun handlerTaskDataRecord-run (self work)
<   (if (eq noWork work)
<       nil
---
> (defun handlerTaskDataRecord-run (self/handlerTaskDataRecord work/packet)
>   (unless (eq noWork work)

The nil was not being used.  It's preferable to use unless.

124c131
< 	(wait)
---
> 	(task-wait)
133c140
< 		(wait)
---
> 		(task-wait)
142c149
< (defun idleTaskDataRecord-run (self work)
---
> (defun idleTaskDataRecord-run (self/idleTaskDataRecord work)
159c166
< (defun workerTaskDataRecord-run (self work)
---
> (defun workerTaskDataRecord-run (self/workerTaskDataRecord work/packet)
161c168
<       (wait)
---
>       (task-wait)
170c177
< 	 ((> i 3) nil)
---
> 	 ((> i 3))

Don't want to return nil yet.

174,175c181,182
< 	 (if (> (workerTaskDataRecord-count self) 256)
< 	     (setf (workerTaskDataRecord-count self) 1))
---
> 	 (when (> (workerTaskDataRecord-count self) 256)
> 	   (setf (workerTaskDataRecord-count self) 1))
182c189
< (defun appendHead (packet queueHead)
---
> (defun appendHead (packet/packet queueHead/packet)
189,191c196,198
< 	    ((eq noWork link) nil)
< 	    (setq mouse link)
< 	    (setq link (packet-link mouse)))
---
> 	    ((eq noWork link))
> 	  (setq mouse link)
> 	  (setq link (packet-link mouse)))
197,198c204,205
<   (setq currentTask nil)
<   (setq currentTaskIdentity nil)
---
>   (setq currentTask null)
>   (setq currentTaskIdentity -1L)
208,209c215
<   (let ((workQ))
<     (setq workQ (createPacket noWork worker workPacketKind))
---
>   (let ((workQ (createPacket noWork worker workPacketKind)))

This makes it easier for type inference.

236c242
< 	 (if tracing (trace-it currentTaskIdentity))
---
> 	 (when tracing (trace-it currentTaskIdentity))
242c248
<     (if (eq noTask tk) (error "findTask failed"))
---
>     (when (eq noTask tk) (error "findTask failed"))
250c256
< (defun queuePacket (packet)
---
> (defun queuePacket (packet/packet)
273,276c279,281
<   (if (>= 0 layout)
<       (progn
<        (format t "~%")
<        (setq layout 30)))
---
>   (when (>= 0 layout)
>     (format t "~%")
>     (setq layout 30))
301,302c306,307
< (defun createPacket (link identity kind)
<   (create-packet link identity kind))
---
> ;; (defun createPacket (link identity kind)
> ;;   (create-packet link identity kind))

Linj already treats create-packet and createPacket as the same name.

304c309
< (defun running (tcb)
---
> (defun running (tcb/taskControlBlock)
324c329
< (defun isTaskHoldingOrWaiting (tcb)
---
> (defun isTaskHoldingOrWaiting (tcb/taskControlBlock)
329c334
< (defun isWaitingWithPacket (tcb)
---
> (defun isWaitingWithPacket (tcb/taskControlBlock)
334c339
< (defun packetNowPending (tcb)
---
> (defun packetNowPending (tcb/taskControlBlock)
340,341c345
< (defun create-taskControlBlock
<   (link identity priority initialWorkQueue initialState privateData)
---
> (defun create-taskControlBlock (link identity priority initialWorkQueue initialState/taskControlBlock privateData)
357c361
< (defun addInput (tcb packet oldTask)
---
> (defun addInput (tcb/taskControlBlock packet oldTask/taskControlBlock)
371,372c375,376
< (defun runTask (tcb)
<   (let ((message nil))
---
> (defun runTask (tcb/taskControlBlock)
>   (let ((message (the packet null)))
384,388c388,392
<   (typecase self
< 	    (deviceTaskDataRecord (deviceTaskDataRecord-run self work))
< 	    (handlerTaskDataRecord (handlerTaskDataRecord-run self work))
< 	    (idleTaskDataRecord (idleTaskDataRecord-run self work))
< 	    (workerTaskDataRecord (workerTaskDataRecord-run self work))))
---
>   (etypecase self
>     (deviceTaskDataRecord (deviceTaskDataRecord-run self work))
>     (handlerTaskDataRecord (handlerTaskDataRecord-run self work))
>     (idleTaskDataRecord (idleTaskDataRecord-run self work))
>     (workerTaskDataRecord (workerTaskDataRecord-run self work))))

Typecase changed to etypecase so that all control flow paths either
return a value or abort.


390c394
< (defun create-packet (link identity kind)
---
> (defun create-packet (link identity kind/long)
396c400
<     (let ((v (make-array 4 :initial-element 0)))
---
>     (let ((v (make-array 4 :element-type 'fixnum :initial-element 0)))
411c415
< (defun deviceInAdd (tk packet)
---
> (defun deviceInAdd (tk/handlerTaskDataRecord packet/packet)
416c420
< (defun workInAdd (tk packet)
---
> (defun workInAdd (tk/handlerTaskDataRecord packet/packet)


And now, the results:

              CMUCL       Allegro        Java
Iterations noopt  opt   noopt  opt   client server
  1000000   0.5   0.3    2.3   1.2    0.5     1.6
  5000000   2.6   1.6    8.9   5.7    1.5     2.2
 25000000   9.7   6.4   24.6  13.7    6.3     4.9
125000000  28.8  18.4  100.9  58.6   16.5    12.5

The noopt means just the normal defaults for optimization.
The opt means that a 

(declaim (optimize (speed 3) (safety 0) (debug 0) (compilation-speed 0)))

was added in the beginning of the file.

Once again, I'm impressed.  And surprised with Allegro performance.
I didn't include results for CLISP because it didn't look to me it
couldn't improve the situation.

Comments?
From: szymon
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87eknuj010.fsf@darkstar.example.net>
Antonio Menezes Leitao <··············@evaluator.pt> writes:

> Comments?

Try GCL 2.6.2.

Regards.
From: Juho Snellman
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <slrnceae8e.fn5.jsnell@melkinpaasi.cs.Helsinki.FI>
<··············@evaluator.pt> wrote:
>              CMUCL       Allegro        Java
>Iterations noopt  opt   noopt  opt   client server
>  1000000   0.5   0.3    2.3   1.2    0.5     1.6
>  5000000   2.6   1.6    8.9   5.7    1.5     2.2
> 25000000   9.7   6.4   24.6  13.7    6.3     4.9
>125000000  28.8  18.4  100.9  58.6   16.5    12.5
[...]
>Comments?

I'm rather suprised. The bottleneck (on SBCL) is accessing special
variables. How are you representing specials in Java?

[ Of course the variables in question might as well not be special;
  they're never rebound, just reassigned. Non-special globals (which
  CL doesn't directly have) would be the right choice. Replacing the
  defvars with a top-level let that wraps the defuns gives me a
  40%-50% improvement. But again, that's a rather sleazy rewrite of
  the benchmark. ]

-- 
Juho Snellman
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87hdsq1nu7.fsf@evaluator.pt>
······@iki.fi (Juho Snellman) writes:

> <··············@evaluator.pt> wrote:
>>              CMUCL       Allegro        Java
>>Iterations noopt  opt   noopt  opt   client server
>>  1000000   0.5   0.3    2.3   1.2    0.5     1.6
>>  5000000   2.6   1.6    8.9   5.7    1.5     2.2
>> 25000000   9.7   6.4   24.6  13.7    6.3     4.9
>>125000000  28.8  18.4  100.9  58.6   16.5    12.5
> [...]
>>Comments?
>
> I'm rather suprised. The bottleneck (on SBCL) is accessing special
> variables. How are you representing specials in Java?

I don't represent specials in Java.  In Linj, defvar and defparameter
are equivalent and they are translated into public static slots.  A
defconstant is translated into a public static final slot.

In Linj, a defvar or defparameter doesn't imply any 'special'
treatment to the declared variable (much less, dynamic scope).  It's
just like a global variable.  However, when someone wants the dynamic
scope he/she can use the fluid-let form to achieve more or less the
same effect.

I could change the compiler to more closely mirror the Common Lisp
behavior but I think that, in most cases, a defvar (or defparameter)
is used to provide global scope and not to provide dynamic scope.  In
this regard, I think Linj does the right thing.

> [ Of course the variables in question might as well not be special;
>   they're never rebound, just reassigned. Non-special globals (which
>   CL doesn't directly have) would be the right choice. Replacing the
>   defvars with a top-level let that wraps the defuns gives me a
>   40%-50% improvement. But again, that's a rather sleazy rewrite of
>   the benchmark. ]

What were the timings before and after your change?

Thanks,

Ant�nio Leit�o.
From: Matthew Danish
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <Pine.LNX.4.58-035.0407021116140.3215@unix45.andrew.cmu.edu>
On Fri, 2 Jul 2004, Antonio Menezes Leitao wrote:
> I could change the compiler to more closely mirror the Common Lisp
> behavior but I think that, in most cases, a defvar (or defparameter)
> is used to provide global scope and not to provide dynamic scope.  In
> this regard, I think Linj does the right thing.

Perhaps when you use it, but I use defvar or defparameter a great deal for
the automatic special declaration.  I would not consider a compiler to be
a Common Lisp compiler if it did not do this, or even close to one.  Far
too much code would break.  I also expect specials to be implemented in a
sane manner w/regards to multiprocessing (though there are no strict
semantics for this established, at least non-MP code should work).
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <874qoq1f7x.fsf@evaluator.pt>
Matthew Danish <·······@andrew.cmu.edu> writes:

> On Fri, 2 Jul 2004, Antonio Menezes Leitao wrote:
>> I could change the compiler to more closely mirror the Common Lisp
>> behavior but I think that, in most cases, a defvar (or defparameter)
>> is used to provide global scope and not to provide dynamic scope.  In
>> this regard, I think Linj does the right thing.
>
> Perhaps when you use it, but I use defvar or defparameter a great deal for
> the automatic special declaration.  I would not consider a compiler to be
> a Common Lisp compiler if it did not do this, or even close to one.  Far
> too much code would break.  I also expect specials to be implemented in a
> sane manner w/regards to multiprocessing (though there are no strict
> semantics for this established, at least non-MP code should work).

Let me stress this one more time: Linj is _not_ Common Lisp.  The Linj
compiler doesn't compile Common Lisp programs, it compiles Linj
programs.

However, Linj is intended for Common Lisp programmers that also need
to produce readable Java programs.  The idea behind Linj is to explore
every possible mapping between Common Lisp constructs and Java
constructs that might allow a Common Lisp programmer to program in
Java more or less as if he/she was programming in Common Lisp.
Unfortunately, these mappings are very difficult to find and some
things must change in order to allow for better Java code generation.
For example, a Linj function is not exactly the same as a Common Lisp
function.  I could use a different form in Linj instead of the
well-known defun to explicitly alert the programmer that Linj
functions have different semantics but this would mean that Common
Lisp programmers would have a harder time programming in Linj just
because there are some subtle differences that only affect a small
number of cases.

The truth is that there are lots of differences between Common Lisp
and Linj and the programmer must know them to be able to deal with the
cases where the differences matter.  However, I would claim that, in
most cases, these differences are not relevant.  This means that
programming in Linj might not be as good as programming in Common Lisp
(at least, IMHO) but it surely is much, much, much nicer than
programming in Java.  The small number of changes that I have to do to
translate Common Lisp benchmarks to Linj benchmarks are empirical
evidence that the mappings are not as bad as they might seem at first
look.

Regarding the use of defvar and defparameter, let's consider the
concept of global variable in Java.  IMHO, the best that we can do in
Java to define something similar to a global variable is to have a
public static slot defined on some class.  It's not exactly the same
but it is sufficiently similar.  And in the case of a global constant?
A Java programmer would answer that a public static final slot would
be the most adequate.

Given the fact Linj wants to allow Common Lisp programmers to program
in Java without having to deal with the horrible Java syntax (and
allowing them to use a large number of the nice things that are
available in Common Lisp), what are the corresponding construct in
Common Lisp?  I mean, what should we use in Common Lisp to define
global variables and global constants?  My answer comes from the
following paragraph extracted from CLTL2:

  The defvar and defparameter special forms are the usual means of
  specifying globally defined variables. The defconstant special form
  is used for defining named constants. 

I don't ignore that there are people that use defvar and defparameter
just for the automatic special declaration.  Sometimes, I'm one of
them (even the Linj compiler uses it) but I would bet that, most of
the times, people use defvar and defparameter just as CLTL2 suggests
and not for its 'specialness'.

Moreover, given the fact that Linj does not implement dynamic scope
(AFAIK, there's no corresponding concept in Java), it should be fairly
obvious to Linj programmers that there's nothing 'special' about
defvar and defparameter in Linj.

Obviously, if you don't like to use defvar or defparameter for this
purpose, it's trivial to define a new form (Linj has macros).

Anyway, I'm glad to hear different opinions.

Thanks,

Ant�nio Leit�o.
From: Thomas Schilling
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <opsaiwanuztrs3c0@news.CIS.DFN.DE>
Antonio Menezes Leitao wrote:

> I don't ignore that there are people that use defvar and defparameter
> just for the automatic special declaration.  Sometimes, I'm one of
> them (even the Linj compiler uses it) but I would bet that, most of
> the times, people use defvar and defparameter just as CLTL2 suggests
> and not for its 'specialness'.
>
> Moreover, given the fact that Linj does not implement dynamic scope
> (AFAIK, there's no corresponding concept in Java), it should be fairly
> obvious to Linj programmers that there's nothing 'special' about
> defvar and defparameter in Linj.
>
> Obviously, if you don't like to use defvar or defparameter for this
> purpose, it's trivial to define a new form (Linj has macros).

I might miss something but AFAIK the most important property of special 
vars is that a let rebinds them not just locally. I.e. I think you could 
simply simulate the specialness by translating

  (let ((*special* form)) ... )

into

  Type _special_bachup = _special_;
  _special_ = form;
  ...
  _special_ = special_backup;

And include this feature with defvar and defparameter as default and add a 
new form (defglobal ...) for simple java-like globals.

But I might be mistaken. (Maybe there's more about specialness than I know 
of.)
-- 
      ,,
     \../   /  <<< The LISP Effect
    |_\\ _==__
__ | |bb|   | _________________________________________________
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87zn6hlbgw.fsf@evaluator.pt>
Thomas Schilling <······@yahoo.de> writes:

> Antonio Menezes Leitao wrote:
>
>> Moreover, given the fact that Linj does not implement dynamic scope
>> (AFAIK, there's no corresponding concept in Java), it should be fairly
>> obvious to Linj programmers that there's nothing 'special' about
>> defvar and defparameter in Linj.
>>
>> Obviously, if you don't like to use defvar or defparameter for this
>> purpose, it's trivial to define a new form (Linj has macros).
>
> I might miss something but AFAIK the most important property of
> special vars is that a let rebinds them not just locally. I.e. I think
> you could simply simulate the specialness by translating
>
>   (let ((*special* form)) ... )
>
> into
>
>   Type _special_bachup = _special_;
>   _special_ = form;
>   ...
>   _special_ = special_backup;
>

That's precisely what fluid-let does (modulo some try-finally to
ensure the correct behaviour even in the presence of exceptions).  But
the resulting code doesn't look very readable.  Linj primary use is to
generate readable Java code in the sense that it could have been
written by a Java programmer (that also happens to know Lisp).  This
goal can't be fullfilled when we try to implement every possible
Common Lisp feature in Java.

> And include this feature with defvar and defparameter as default and
> add a new form (defglobal ...) for simple java-like globals.

That's one possibility.  The other one that I'm using for the moment
allows easier translations of Common Lisp code because, as I claimed
previously, most uses of defvar and defparameter are done to achieve
global scope and not dynamic scope.

Thanks for the comments,

Ant�nio Leit�o.
From: Thomas F. Burdick
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <xcv1xjqz09k.fsf@famine.OCF.Berkeley.EDU>
Antonio Menezes Leitao <··············@evaluator.pt> writes:

> Thomas Schilling <······@yahoo.de> writes:
>
> >   Type _special_bachup = _special_;
> >   _special_ = form;
> >   ...
> >   _special_ = special_backup;
> >
> 
> That's precisely what fluid-let does (modulo some try-finally to
> ensure the correct behaviour even in the presence of exceptions).  But
> the resulting code doesn't look very readable.  Linj primary use is to
> generate readable Java code in the sense that it could have been
> written by a Java programmer (that also happens to know Lisp).

If it's any help, when I want dynamic binding in a language that
doesn't have it, I hack up a dynamic binding stack, and manage it by
hand.  Something like the following pseudocode:

  try {
    bind (@my_var, 1);
    bind (@another_var, 2);
    bind (@sum, x + y + binding(@z));
    some_fn();
    ...
  } finally {
    unbind (3);
  }

Real Java would be a little grosser, but not too bad, I wouldn't imagine.
From: Pascal Costanza
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cc4drf$rit$1@newsreader2.netcologne.de>
Antonio Menezes Leitao wrote:

> Regarding the use of defvar and defparameter, let's consider the
> concept of global variable in Java.  IMHO, the best that we can do in
> Java to define something similar to a global variable is to have a
> public static slot defined on some class.  It's not exactly the same
> but it is sufficiently similar.  And in the case of a global constant?
> A Java programmer would answer that a public static final slot would
> be the most adequate.

I think the concept of a special variable is too important to be missing 
from something like Linj. In fact, the Java folks have also rediscovered 
them, at least partly. Check out java.lang.ThreadLocal - IIRC, Sun tries 
hard to optimize thread locals, which means that there is a demand for it.

The straightforward way to implement special variables would be to store 
a List in a ThreadLocal, and to push a new value for each dynamic scope 
to that list.

> Given the fact Linj wants to allow Common Lisp programmers to program
> in Java without having to deal with the horrible Java syntax (and
> allowing them to use a large number of the nice things that are
> available in Common Lisp), what are the corresponding construct in
> Common Lisp?  I mean, what should we use in Common Lisp to define
> global variables and global constants?

I understand your concern. I would suggest to model globals according to 
the ISLISP design - it provides both lexical and dynamic global 
variables via defglobal and defdynamic, IIRC. See http://www.islisp.info/

If you leave this to Linj users, it is likely that they won't make use 
of the JVM optimizations for thread locals.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87vfh5l85m.fsf@evaluator.pt>
Pascal Costanza <········@web.de> writes:

> Antonio Menezes Leitao wrote:
>
>> Regarding the use of defvar and defparameter, let's consider the
>> concept of global variable in Java.  IMHO, the best that we can do in
>> Java to define something similar to a global variable is to have a
>> public static slot defined on some class.  It's not exactly the same
>> but it is sufficiently similar.  And in the case of a global constant?
>> A Java programmer would answer that a public static final slot would
>> be the most adequate.
>
> I think the concept of a special variable is too important to be
> missing from something like Linj. In fact, the Java folks have also
> rediscovered them, at least partly. Check out java.lang.ThreadLocal -
> IIRC, Sun tries hard to optimize thread locals, which means that there
> is a demand for it.

I know about thread-locals.  I even have some ideas about introducing
syntax in Linj just to deal with thread-locals.  However, the problem
regarding dynamic scope is a bit different as Common Lisp doesn't even
define the semantics of dynamic scope in the presence of different
threads of execution.  I know that there's a kind of agreement about
what should be done in this case but, IMHO, being a thread-local
variable and being a dynamically scoped variable are two different
concepts.  You might want one or the other or both.

The same is true about being a globally scoped variable (I mean, with
indefinite scope and indefinite extent) and being a dynamically scoped
variable (I mean, with indefinite scope and dynamic extent).  In Java,
when you want a variable with indefinite scope and indefinite extent,
you just declare a public static variable (I know it's not exactly the
same thing but it looks like the closest thing). When you want a
variable with indefinite scope and dynamic extent, you also declare a
public static variable but you have to simulate the dynamic extent by
saving the previous value of the variable, assigning the new one and
restoring the previous one in the end.  Linj also implements this
behaviour, but I decided to use defvar/defparameter just for the
indefinite scope part and fluid-let for the dynamic extent.  This
informs the Linj programmer about the effects on the generated Java
code.

> The straightforward way to implement special variables would be to
> store a List in a ThreadLocal, and to push a new value for each
> dynamic scope to that list.

In my experience, being straighforward to implement usually means that
the generate code that doesn't look like it was written by a human
programmer.

We must not forget that Linj's goal is to produce readable Java code.
If you are not concerned about readability, then there are lots of
things that you can implement but, in this case, I would recomend
something that compiles directly to JVM such as ArmedBear Lisp.

>> Given the fact Linj wants to allow Common Lisp programmers to program
>> in Java without having to deal with the horrible Java syntax (and
>> allowing them to use a large number of the nice things that are
>> available in Common Lisp), what are the corresponding construct in
>> Common Lisp?  I mean, what should we use in Common Lisp to define
>> global variables and global constants?
>
> I understand your concern. I would suggest to model globals according
> to the ISLISP design - it provides both lexical and dynamic global
> variables via defglobal and defdynamic, IIRC. See
> http://www.islisp.info/

I did look at ISLISP when I was thinking about Linj.  In the
beginning, Linj was modeled as a mixture between Scheme and Java but,
although I like Scheme a lot, I became convinced that the real benefit
was on those nice Common Lisp features that might not be theoretically
essential but that are pragmatically fundamental: lambda lists,
macros, method combination, etc.  I could invent new syntax for all
this stuff but what's the point?  These concepts have been distilled
for a very long time and are perfectly expressed in Common Lisp.  In
the end, I decided to make Linj look like Common Lisp as much as I
could, even though I would have to assign different semantics to some
things.  Whenever I changed the semantics of some form (as in the
defvar/defparameter case), I tried that the new semantics would cover
its pragmatical use in Common Lisp.

Obviously, I might be wrong about what is the Common Lisp pragmatics
and there might be Common Lisp programmers whose programming style is
totally incompatible with Linj because they explore the other semantic
features that I didn't include in Linj.  But, once again, Linj is not
Common Lisp.  Nobody should expect that a Common Lisp program will run
in Linj without modification.

Thanks for the comments,

Ant�nio Leit�o.
From: Pascal Costanza
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cc62c9$177$1@newsreader2.netcologne.de>
Antonio Menezes Leitao wrote:

> I know about thread-locals.  I even have some ideas about introducing
> syntax in Linj just to deal with thread-locals.  However, the problem
> regarding dynamic scope is a bit different as Common Lisp doesn't even
> define the semantics of dynamic scope in the presence of different
> threads of execution.  I know that there's a kind of agreement about
> what should be done in this case but, IMHO, being a thread-local
> variable and being a dynamically scoped variable are two different
> concepts.  You might want one or the other or both.

Well, I think that new bindings of special variables shouldn't affect 
other threads, and that this is clearly the right thing. I don't see how 
affecting other threads randomly would yield useful behavior. (This 
means that I don't think that this is just some kind of accidental 
agreement.)

>>The straightforward way to implement special variables would be to
>>store a List in a ThreadLocal, and to push a new value for each
>>dynamic scope to that list.
> 
> In my experience, being straighforward to implement usually means that
> the generate code that doesn't look like it was written by a human
> programmer.

Have you tried this with thread locals? I think they are readable, 
especially in the generically-typed variant.

> We must not forget that Linj's goal is to produce readable Java code.
> If you are not concerned about readability, then there are lots of
> things that you can implement but, in this case, I would recomend
> something that compiles directly to JVM such as ArmedBear Lisp.

Sure, I understand your concerns, and I am thinking about your questions 
especially from that perspective. I have seen (prominent!) Java code in 
which dynamic scoping was simulated in a very cumbersome way. (Actually, 
it's the Java compiler provided by Sun.) I think expressing these things 
with thread locals would be much more readable.

> I did look at ISLISP when I was thinking about Linj.  In the
> beginning, Linj was modeled as a mixture between Scheme and Java but,
> although I like Scheme a lot, I became convinced that the real benefit
> was on those nice Common Lisp features that might not be theoretically
> essential but that are pragmatically fundamental: lambda lists,
> macros, method combination, etc.  I could invent new syntax for all
> this stuff but what's the point?  These concepts have been distilled
> for a very long time and are perfectly expressed in Common Lisp.  In
> the end, I decided to make Linj look like Common Lisp as much as I
> could, even though I would have to assign different semantics to some
> things.  Whenever I changed the semantics of some form (as in the
> defvar/defparameter case), I tried that the new semantics would cover
> its pragmatical use in Common Lisp.

Well, I think you have made the wrong choice here, and the fact that you 
are using fluid-let for dynamically-scoped variables is an indication 
that you are still too much of a Schemer. ;)

I think it's better to go all the way either in the direction of Scheme 
or in the direction of Common Lisp, but not stop somewhere in between, 
because then you are creating unnecessary problems. The example of 
global variables is likely to create problems when people choose to port 
existing Lisp code to Linj, and these would be gratuitous problems.

ISLISP is a Lisp dialect that Kent Pitman has described as culturally 
compatible to Common Lisp, i.e. it is much closer to Common Lisp than to 
Scheme in spirit (being a Lisp-2, using essentially a subset of CLOS, 
and so on). IIUC, it was designed so that ISLISP programs can be 
relatively easily ported to Common Lisp. The only thing that I am 
suggesting is to use ISLISP's defglobal for lexically scoped globals and 
  defdynamic for dynamically scoped globals. The effect would be that 
someone whose goal is just to create readable Java programs would use 
defglobal, someone who wants to use dynamic scoping would use defdynamic 
(and because of dynamic-let for binding and dynamic for lookup, you 
wouldn't have a hard time to detect those cases in your compiler, just 
as is the case for fluid-let), and using defvar and defparameter with 
possibly surprising results wouldn't be possible.

It's all about just using different names, that's all.

> Obviously, I might be wrong about what is the Common Lisp pragmatics
> and there might be Common Lisp programmers whose programming style is
> totally incompatible with Linj because they explore the other semantic
> features that I didn't include in Linj.  But, once again, Linj is not
> Common Lisp.  Nobody should expect that a Common Lisp program will run
> in Linj without modification.

Yes, I have got that. ;) See my sig for more details. ;)


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87n02hkztu.fsf@evaluator.pt>
Pascal Costanza <········@web.de> writes:

> Antonio Menezes Leitao wrote:
>
>> I know about thread-locals.  I even have some ideas about introducing
>> syntax in Linj just to deal with thread-locals.  However, the problem
>> regarding dynamic scope is a bit different as Common Lisp doesn't even
>> define the semantics of dynamic scope in the presence of different
>> threads of execution.  I know that there's a kind of agreement about
>> what should be done in this case but, IMHO, being a thread-local
>> variable and being a dynamically scoped variable are two different
>> concepts.  You might want one or the other or both.
>
> Well, I think that new bindings of special variables shouldn't affect
> other threads, and that this is clearly the right thing. I don't see
> how affecting other threads randomly would yield useful
> behavior. (This means that I don't think that this is just some kind
> of accidental agreement.)

It might not yield useful behavior but automatically making all
special variables also thread-local might give you bad performance.
Sometimes you want dynamic behavior that you know that doesn't cause
problems with threads.  In this case, you might not want to pay the
price for something that you don't use.  It is good have the choice.

This is also the perfect example of the situation that occurred in the
RICHARDS benchmark.  Juho Snellman profiled it in SBCL and discovered
that the bootleneck was accessing the special variables that happen to
be there just because they needed globally scoped variables.  It would
be better if we could distinguish (as you suggested with ISLISP)
between the different uses of defvar/defparameter.

>>>The straightforward way to implement special variables would be to
>>>store a List in a ThreadLocal, and to push a new value for each
>>>dynamic scope to that list.
>> In my experience, being straighforward to implement usually means
>> that
>> the generate code that doesn't look like it was written by a human
>> programmer.
>
> Have you tried this with thread locals? I think they are readable,
> especially in the generically-typed variant.

Not yet.

>> We must not forget that Linj's goal is to produce readable Java code.
>> If you are not concerned about readability, then there are lots of
>> things that you can implement but, in this case, I would recomend
>> something that compiles directly to JVM such as ArmedBear Lisp.
>
> Sure, I understand your concerns, and I am thinking about your
> questions especially from that perspective. I have seen (prominent!)
> Java code in which dynamic scoping was simulated in a very cumbersome
> way. (Actually, it's the Java compiler provided by Sun.) I think
> expressing these things with thread locals would be much more readable.
>
>> I did look at ISLISP when I was thinking about Linj.  In the
>> beginning, Linj was modeled as a mixture between Scheme and Java but,
>> although I like Scheme a lot, I became convinced that the real benefit
>> was on those nice Common Lisp features that might not be theoretically
>> essential but that are pragmatically fundamental: lambda lists,
>> macros, method combination, etc.  I could invent new syntax for all
>> this stuff but what's the point?  These concepts have been distilled
>> for a very long time and are perfectly expressed in Common Lisp.  In
>> the end, I decided to make Linj look like Common Lisp as much as I
>> could, even though I would have to assign different semantics to some
>> things.  Whenever I changed the semantics of some form (as in the
>> defvar/defparameter case), I tried that the new semantics would cover
>> its pragmatical use in Common Lisp.
>
> Well, I think you have made the wrong choice here, and the fact that
> you are using fluid-let for dynamically-scoped variables is an
> indication that you are still too much of a Schemer. ;)

As paradoxically as it might seem to you, before I learned Scheme I
was both a FranzLisp programmer and an EmacsLisp programmer.
Franzlisp is a dynamically scoped language (unless you compiled your
programs) just like EmacsLisp so I was quite used to
dynamically-scoped variables without ever using fluid-let.

The rational for introducing fluid-let in Linj was precisely for the
programmer to understand that a fluid-let is completely different from
a let and that it generates completely different Java code.  A
fluid-let in your program is a sign that the Java code doesn't look
nice.  If I just decide to amalgamate fluid-let with the normal let,
the programmer wouldn't get this feedback.

I could have chosen a different name (e.g., dynamic-let or
with-temporary-value or whatever) but I have the feeling that the
large majority of Common Lispers also happen to know a bit of Scheme
so it seemed simpler to use an already known form than to use
something from a lesser-known language or to invent something new.

> I think it's better to go all the way either in the direction of
> Scheme or in the direction of Common Lisp, but not stop somewhere in
> between, because then you are creating unnecessary problems. The
> example of global variables is likely to create problems when people
> choose to port existing Lisp code to Linj, and these would be
> gratuitous problems.

I think that, with the requirement of readable Java code generation,
you can't go all the way in either direction.  Of course, if you drop
this requirement and accept a different one such as targeting
unreadable Java code or even targeting Java bytecode, then you don't
need Linj at all and you should be using Kawa (or Bigloo) or Armed
Bear Lisp, depending on the direction you want to go.

Anyway, I don't think that Linj is in-between Common Lisp or Scheme.
The fluid-let is the only form (as far as I remember) that Linj took
from Scheme.  And I took it from Scheme because there was nothing
similar (I mean, with the requirement of being syntactically different
from a let) that I could use from Common Lisp.

Moreover, Linj was not made to allow porting existing Lisp code.  It
might be used for that purpose and I might decide to change Linj in
order to simplify that task (I had to make a few changes in Linj to
allow easier translation of the boyer and richard benchmarks).  Its
main purpose, however, is to allow one to use the huge Java APIs with
a Lisp flavor.

> ISLISP is a Lisp dialect that Kent Pitman has described as culturally
> compatible to Common Lisp, i.e. it is much closer to Common Lisp than
> to Scheme in spirit (being a Lisp-2, using essentially a subset of
> CLOS, and so on). IIUC, it was designed so that ISLISP programs can be
> relatively easily ported to Common Lisp. The only thing that I am
> suggesting is to use ISLISP's defglobal for lexically scoped globals
> and defdynamic for dynamically scoped globals. The effect would be
> that someone whose goal is just to create readable Java programs would
> use defglobal, someone who wants to use dynamic scoping would use
> defdynamic (and because of dynamic-let for binding and dynamic for
> lookup, you wouldn't have a hard time to detect those cases in your
> compiler, just as is the case for fluid-let), and using defvar and
> defparameter with possibly surprising results wouldn't be possible.

I agree with you that you might get strange errors due to the
different semantics between Common Lisp's defvar and Linj's defvar.
And, to be honest, I must say that in the beginning, Linj didn't have
defvar or defparameter or defconstant but a few other forms named
defshared and defconst (I didn't pick them from Scheme :-).  Then, to
simplify the translation to Linj of all those Common Lisp programs
that were using defvar or defparameter just to define global
variables, I decided to introduce macros that would translate those
forms to defshared.  The other option would have been to change the
original Common Lisp forms but I was (am) too lazy.

> It's all about just using different names, that's all.

But that's not so simple.  I agree with you that theoretically it
would be better to have different names for different concepts but
this would make it impossible to translate even the simplest Common
Lisp program to Linj as there's nothing in Linj that has the exact
same semantics as in Common Lisp.  You have to make compromises and I
think that most of the compromises done in Linj reflect the common use
of the forms in Common Lisp.  The same thing happens in other
contexts.  If you look, e.g., at the Common Lisp compatibility package
for EmacsLisp, you will see that there are some fundamental elements
(e.g., the let) that have completely different semantics.  In most
cases, it will not cause you any problems but there will always be
situations where you will have to change your Common Lisp code (and
use the lexical-let or whatever different name they introduced) in
order for it to run in EmacsLisp the same way it did in Common Lisp.

As Kent Pitman once said, there are no solutions, just compromises.

Thanks,

Ant�nio Leit�o.
From: Juho Snellman
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <slrncedjsl.4de.jsnell@melkinpaasi.cs.Helsinki.FI>
<··············@evaluator.pt> wrote:
>······@iki.fi (Juho Snellman) writes:
>>   Replacing the
>>   defvars with a top-level let that wraps the defuns gives me a
>>   40%-50% improvement. But again, that's a rather sleazy rewrite of
>>   the benchmark. ]
>
>What were the timings before and after your change?

Turns out that it was that much of an improvement only for threaded
SBCL. For (richards 125000000) on a Athlon 64 2800:

                   SBCL        SBCL         CMUCL   CMUCL 
		   (Threaded) (Nonthreaded)         (Block-compiled)
Original           20.89      13.79         13.42   20.00
Without specials   11.21      11.27         16.96   12.12

(No, I don't really understand the performance characteristics of
CMUCL here. Probably some subtle error I've made). 

-- 
Juho Snellman
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cc4om0$rfr$1@ulric.tng.de>
Antonio Menezes Leitao schrieb:

> And now, the results:
> 
>               CMUCL       Allegro        Java
> Iterations noopt  opt   noopt  opt   client server
>   1000000   0.5   0.3    2.3   1.2    0.5     1.6
>   5000000   2.6   1.6    8.9   5.7    1.5     2.2
>  25000000   9.7   6.4   24.6  13.7    6.3     4.9
> 125000000  28.8  18.4  100.9  58.6   16.5    12.5
> 
> The noopt means just the normal defaults for optimization.
> The opt means that a 
> 
> (declaim (optimize (speed 3) (safety 0) (debug 0) (compilation-speed 0)))
> 
> was added in the beginning of the file.
> 
> Once again, I'm impressed.  And surprised with Allegro performance.
> I didn't include results for CLISP because it didn't look to me it
> couldn't improve the situation.
> 
> Comments?

Amazing that the commercial version which costs hundreds of dollars is 
not at least as fast as the free Lisp. Would be interesting to hear why 
it is this way.

And well, a suggestion: try Java 1.5.
This should be even faster...


Andr�
--
From: Christopher C. Stacy
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <u6595hq04.fsf@news.dtpq.com>
>>>>> On Sat, 03 Jul 2004 00:47:46 +0200, Andr� Thieme ("Andr�") writes:

 Andr�> Antonio Menezes Leitao schrieb:
 >> And now, the results:
 >> CMUCL       Allegro        Java
 >> Iterations noopt  opt   noopt  opt   client server
 >> 1000000   0.5   0.3    2.3   1.2    0.5     1.6
 >> 5000000   2.6   1.6    8.9   5.7    1.5     2.2
 >> 25000000   9.7   6.4   24.6  13.7    6.3     4.9
 >> 125000000  28.8  18.4  100.9  58.6   16.5    12.5
 >> The noopt means just the normal defaults for optimization.
 >> The opt means that a (declaim (optimize (speed 3) (safety 0) (debug
 >> 0) (compilation-speed 0)))
 >> was added in the beginning of the file.
 >> Once again, I'm impressed.  And surprised with Allegro performance.
 >> I didn't include results for CLISP because it didn't look to me it
 >> couldn't improve the situation.
 >> Comments?

 Andr�> Amazing that the commercial version which costs hundreds of
 Andr�> dollars is not at least as fast as the free Lisp. Would be
 Andr�> interesting to hear why it is this way.

It's not amazing at all, since the compiler is but one piece
of what you're buying when you get the commercial product.

I haven't used their product, but from everything I've ever seen, 
Franz has a very good compiler and they are definitely interested
in competing, but they have also invested a huge amount in other
areas of their Allegro product. Franz can probably speed up that
benchmark, if it's important.  I am sure they are driven by their
customers' requirements.

I am also sure that one benchmark like the one above, in isolation,
is not very interesting in the big picture of system performance.
I don't want to stifle people's enthusiasm for Lisp runtime
performance, but I do question how important it is.

Unless you are working on applications that really mirror that
specific benchmark, trying to sell Lisp as the fastest performer 
on that benchmark seems stupid.  On the other hand, if your customer
is a some kind of idiot or a group of myopic religous fanatics,
incapable of being educated on the real benefits of Lisp, then 
performing well on some random benchmark could indeed be a very 
critical step in the marketing of the technology.
(In that case, you have my sympathetic condolences.)

In the companies where I have worked, the kind of benchmarking that 
I have always used when selecting such a major technology, is to do
an analysis of the application performance requirements in terms of
algorithm and data structure analysis, resulting memory issues and
nner loops of numerics or whatever, and IO.  Then we (perhaps with
expert help from the consultants from the offering firms) develop
a working facsimile of that application that emulates the demands.
For an existing application, in the case of some technologies the
result might even represent the actual prototype or proto-port.
Then we run it and, working with experts as needed, tune it.
Then we can see how well it works compared to the others.

For the amount of money being invested in a serious project,
doing anything less is rather an incompetent joke.
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <cbsl30$lln$1@ulric.tng.de>
Mark McConnell schrieb:

> Thanks for the extra testing.  The result still makes me sad, though
> you point out we shouldn't put too much confidence in it.

You should not forget that Java 1.5 is now it. This one is optimizing 
much better for speed than 1.4.x
So now Java should be very close to CLs speed.


Andr�
--
From: szymon
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87isd6j0f3.fsf@darkstar.example.net>
Antonio Menezes Leitao <··············@evaluator.pt> writes:

> N  CMUCL  CLISP Allegro ServerVM
> 0   0.04   0.14   0.02   0.05
> 1   0.12   0.84   0.18   0.13
> 2   0.37   2.40   0.51   0.43
> 3   1.18   6.28   1.46   1.11
> 4   2.94  18.24   5.30   3.68
> 5  11.81  69.04  24.04  15.81
>
> N  CMUCL  CLISP Allegro ServerVM
> 0   0.02   0.13   0.03   0.02
> 1   0.17   0.84   0.18   0.13
> 2   0.40   2.32   0.51   0.40
> 3   1.02   6.57   1.45   1.08
> 4   3.03  17.99   4.82   3.71
> 5  13.03  70.86  23.35  15.37
>
> The results are not very different from the previous ones I published
> and that I repeat below:
>
> N  CMUCL  CLISP Allegro ServerVM
> 0   0.04   0.13   0.04   0.02
> 1   0.13   0.84   0.26   0.18
> 2   0.41   2.31   0.72   0.50
> 3   1.25   6.58   1.99   1.46
> 4   3.22  17.87   6.36   3.89
> 5  12.60  69.65  26.97  19.25

Try GCL262: [ http://www.gnu.org/software/gcl/RELEASE-2.6.2.html ]

BOYER Benchmark
 
GCL 2.6.2:     1.000 
 
CMUCL 18e-9:   2.200 
 
CLISP 2.33-2:  9.869

Regards, Szymon.
From: Camm Maguire
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <54lli2pdhz.fsf@intech19.enhanced.com>
Greetings!  Coincidentally, we've been looking at the Boyer benchmark
too in testing the recent GCL 2.6.2 release. Thought it might be of
interest to post some GCL results here too (using the boyer benchmark
version posted in this thread):

All times are reported in real time/gc time.

n   GCL-2.6.2   CMUCL 18e  CLISP 2.33.2

0   0.03/0.00   0.04/0.00     0.17/0.01
1   0.21/0.07   0.25/0.00     1.14/0.05
2   0.46/0.12   0.67/0.02     3.08/0.14
3   1.20/0.26   1.76/0.08     8.15/0.50
4   3.74/0.95   5.30/0.69    23.45/1.46
5  12.32/3.72  15.80/2.11    79.51/7.55


All lisps here are the latest versions in Debian unstable.  GCL was
run in ANSI mode.  The machine was a dual Xeon 2.4Ghz.  We already
know that the relative GCL/CMUCL performance can vary somewhat by
machine, presumably influenced by cache size and cpu/memory bandwidth
ratios.  It is clear for example that CMUCL is doing a better job on
the memory layout/access times which predominate in the gc time
component.  On this particular machine, again presumably, memory
access is not the rate limiting step, and the results are more
governed by in cache cpu performance.

All that one might reasonably conclude from this exercise is that in
some cases, GCL is about as fast as CMUCL.

A few extra notes.  GCL comes with an automatic function proclamation
feature which is useful in optimizing the compile, for both GCL and
CMUCL (at least).  One uses it as follows:

(compiler::emit-fn t)
(compile-file "foo.lisp")
(compiler::make-all-proclaims "foo.fn")
(load "sys-proclaim.lisp")
(compile-file "foo.lisp")

This is not simply bundled into compile-file as it is capable of
generating cross-referencing information across many files that can be
useful in optimizing a real system.  The above tests had the
sys-proclaim.lisp file loaded into each lisp before running
compile-file.  What is interesting is that on my machine at least,
this measurably helped the cmucl compile over a 'vanilla'
compile-file, and the insertion of 

(declaim (optimize (speed 3) (safety 0) (debug 0) (compilation-speed
0)))

at the top of the lisp source file actually degraded cmucl performance
from the vanilla version.  The fastest cmucl numbers are reported
above. 

Take care,


Antonio Menezes Leitao <··············@evaluator.pt> writes:

> ···············@yahoo.com (Mark McConnell) writes:
> 
> > To clarify: I'm concerned the test was unfair to Lisp.  Java's
> > compiler tries to optimize for speed, but Lisp won't try [or won't try
> > its hardest] unless you say (proclaim '(optimize speed)).  Antonio, is
> > there a chance you could run the test again with that line included?
> 
> Sure.  I added a 
> 
> (declaim (optimize (speed 3) (safety 0) (debug 0) (compilation-speed 0)))
> 
> at the beginning of the (Common Lisp) file, recompiled it and timed it
> again.  Here are the results of two runs (I also run the Java code
> again):
> 
> N  CMUCL  CLISP Allegro ServerVM
> 0   0.04   0.14   0.02   0.05
> 1   0.12   0.84   0.18   0.13
> 2   0.37   2.40   0.51   0.43
> 3   1.18   6.28   1.46   1.11
> 4   2.94  18.24   5.30   3.68
> 5  11.81  69.04  24.04  15.81
> 
> N  CMUCL  CLISP Allegro ServerVM
> 0   0.02   0.13   0.03   0.02
> 1   0.17   0.84   0.18   0.13
> 2   0.40   2.32   0.51   0.40
> 3   1.02   6.57   1.45   1.08
> 4   3.03  17.99   4.82   3.71
> 5  13.03  70.86  23.35  15.37
> 
> The results are not very different from the previous ones I published
> and that I repeat below:
> 
> N  CMUCL  CLISP Allegro ServerVM
> 0   0.04   0.13   0.04   0.02
> 1   0.13   0.84   0.26   0.18
> 2   0.41   2.31   0.72   0.50
> 3   1.25   6.58   1.99   1.46
> 4   3.22  17.87   6.36   3.89
> 5  12.60  69.65  26.97  19.25
> 
> I guess the Boyer benchmark doesn't show much opportunity for
> optimization.
> 
> One last note:
> 
> I think we shouldn't put too much confidence in these numbers.  My
> test machine is one of those new Centrinos that dynamically adjusts
> the processor speed.  This might cause inconsistent timings.  One
> strange phenomena is the larger variance of the JVM compared with the
> Lisps.  In the same Common Lisp environment I get (more or less)
> consistent timings, but in the JVM I get from 15 s to 25 s for the
> last test case (apparently, depending on the day of the test :-).
> 
> Anyway, given the investment being done in Java compared with the
> investment being done in Common Lisp, I foresee difficult times for
> Common Lisp compilers that want to compete with Java for speed.
> Fortunately, speed is the least of my concerns.  Usually, all my code
> is compiled with (declaim (optimize (speed 0) (safety 3) (debug 3))).
> 
> Best regards,
> 
> Ant�nio Leit�o.

-- 
Camm Maguire			     			····@enhanced.com
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <87zn6iz4hg.fsf@evaluator.pt>
Camm Maguire <····@enhanced.com> writes:

> Greetings!  Coincidentally, we've been looking at the Boyer benchmark
> too in testing the recent GCL 2.6.2 release. Thought it might be of
> interest to post some GCL results here too (using the boyer benchmark
> version posted in this thread):
>
> All times are reported in real time/gc time.
>
> n   GCL-2.6.2   CMUCL 18e  CLISP 2.33.2
>
> 0   0.03/0.00   0.04/0.00     0.17/0.01
> 1   0.21/0.07   0.25/0.00     1.14/0.05
> 2   0.46/0.12   0.67/0.02     3.08/0.14
> 3   1.20/0.26   1.76/0.08     8.15/0.50
> 4   3.74/0.95   5.30/0.69    23.45/1.46
> 5  12.32/3.72  15.80/2.11    79.51/7.55
>
>
> All lisps here are the latest versions in Debian unstable.  GCL was
> run in ANSI mode.  The machine was a dual Xeon 2.4Ghz. 

My timings were also for the latest versions in Debian unstable.
Comparing your timings with mine, I conclude the my 1.6GHz centrino
laptop is faster than your dual Xeon 2.4GHz.  I'm happy :-)
From: Juho Snellman
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <slrncdjkgu.p4e.jsnell@melkinpaasi.cs.Helsinki.FI>
<··············@evaluator.pt> wrote:
>548a546
>>   (setup)
>
>Added a setup call before each test so that the situation becomes more
>similar to Java where the setup must also be done on each test.
[...]
>The Common Lisp version was tested inside the CMUCL environment with
>all the necessary stuff loaded so no CMUCL startup and shutdown time
>was included.

The setup should only be done once, otherwise it'll end up stuffing
the plists with duplicates:

CL-USER[2]: (progn (setup) (get 'car 'lemmas))
((EQUAL (CAR (GOPHER X)) (IF (LISTP X) (CAR (FLATTEN X)) (ZERO))))
CL-USER[3]: (progn (setup) (get 'car 'lemmas))
((EQUAL (CAR (GOPHER X)) (IF (LISTP X) (CAR (FLATTEN X)) (ZERO)))
 (EQUAL (CAR (GOPHER X)) (IF (LISTP X) (CAR (FLATTEN X)) (ZERO))))

This can have a rather significant effect on the latter tests. For
example on one computer:

(time (test-boyer 5))   ; 13.41 seconds of user run time
(dotimes (i 5) (setup)) 
(time (test-boyer 5))   ; 22.38 seconds of user run time

-- 
Juho Snellman
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time? [LONG]
Date: 
Message-ID: <871xk67z6l.fsf@evaluator.pt>
······@iki.fi (Juho Snellman) writes:

> <··············@evaluator.pt> wrote:
>>548a546
>>>   (setup)
>>
>>Added a setup call before each test so that the situation becomes more
>>similar to Java where the setup must also be done on each test.
> [...]
>>The Common Lisp version was tested inside the CMUCL environment with
>>all the necessary stuff loaded so no CMUCL startup and shutdown time
>>was included.
>
> The setup should only be done once, otherwise it'll end up stuffing
> the plists with duplicates:
> CL-USER[2]: (progn (setup) (get 'car 'lemmas))
> ((EQUAL (CAR (GOPHER X)) (IF (LISTP X) (CAR (FLATTEN X)) (ZERO))))
> CL-USER[3]: (progn (setup) (get 'car 'lemmas))
> ((EQUAL (CAR (GOPHER X)) (IF (LISTP X) (CAR (FLATTEN X)) (ZERO)))
>  (EQUAL (CAR (GOPHER X)) (IF (LISTP X) (CAR (FLATTEN X)) (ZERO))))

Gasp!  You are right, of course.  

> This can have a rather significant effect on the latter tests. For
> example on one computer:
>
> (time (test-boyer 5))   ; 13.41 seconds of user run time
> (dotimes (i 5) (setup)) 
> (time (test-boyer 5))   ; 22.38 seconds of user run time
>

In the final results that I presented, the setup was done only once
before timing the computation.  The problem is that I'm not sure that
all the tests were done on a fresh lisp environment (to avoid calling
setup twice) so I decided to repeat all the tests again but this time
making sure the setup is done only once.

Here are the new results:

N CMUCL  CLISP Allegro ServerVM
0  0.04   0.13   0.04  0.02
1  0.13   0.84   0.26  0.18
2  0.41   2.31   0.72  0.50
3  1.25   6.58   1.99  1.46
4  3.22  17.87   6.36  3.89
5 12.60  69.65  26.97 19.25

So, I must apologize for saying bad things about CMUCL. It's a fine
compiler, as is obvious from the above results (it's the compiler I
mostly use so it's good news for me, too).  The other Common Lisp
compilers do not show any significant differences from what I
presented in my previous comparison (most probably the tests were done
correctly on all compilers except CMUCL).

What is strange is that I can't reproduce the results that I got
yesterday with the Java version.  But I'm sure that I'm running the
same test case.  Go figure.

Thanks for the correction and sorry for the wrong results.

Ant�nio Leit�o.
From: Antonio Menezes Leitao
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <pan.2004.06.19.08.05.49.129863@evaluator.pt>
On Fri, 18 Jun 2004 14:46:54 -0400, Joe Marshall wrote:

> Antonio Menezes Leitao <··············@evaluator.pt> writes:
> 
>> On Wed, 16 Jun 2004 19:19:26 +0000, Kenny Tilton wrote:
>>
>>> Anybody got the Linj output for the following? :) kt
>>
>> I did. It's really ugly! But I had to make a few changes (Linj is not
>> exactly Common Lisp).
>>
>> However, I'm unsure I got it right.  For example, the last few lines are:
>>
>> (defun test-boyer (n)
>>   (setq *rewrite-count* 0)
>>   (let ((answer (test n)))
>>     (format t "~&~s" rewrite-count)))
>>
>> Shouldn't the reference rewrite-count be *rewrite-count* instead?
> 
> Yes.  Typo.
> 
>> Are there any test cases to test the program correctness?
> 
>      n      rewrites
> 
>      0         95024
>      1        591777
>      2       1813975
>      3       5375678
>      4      16445406
>      5      51507739

We must be talking about different programs.  I can't get those results in
CMUCL.  Can you send me the exact program that produced those results?

Thanks in advance.
From: Joe Marshall
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <y8mjze43.fsf@comcast.net>
Antonio Menezes Leitao <··············@evaluator.pt> writes:

> We must be talking about different programs.  I can't get those results in
> CMUCL.  Can you send me the exact program that produced those results?

I just tested this, and it produces the expected results.  It corrects
the typo from before and re-orders the false-term and true-term
definitions to avoid a warning, but is otherwise unchanged.  Did you
run SETUP prior to running TEST?  You'd get really screwy results if
you did not.

It would be interesting to see how this would do if it were written in
Java with an eye to how a Java weenie would do it:  A term would be a
base class and there would be empty, atomic (and numeric), and
compound terms.  Most of the code would end up being methods on terms.
A lot of the COND expressions would turn into method dispatch (you
wouldn't write things like  (if (not (consp term)) ...) but rather
specialize the method differently on atomic and compound terms). 


-------------------------------------------------------------------
;;; Boyer benchmark, Bob Boyer + fixes by Henry Baker

(in-package "CL-USER")

(defun setup ()
  (add-lemma-list
   '((equal (compile form)
	    (reverse (codegen (optimize form)
			      (nil))))
     (equal (eqp x y)
	    (equal (fix x)
		   (fix y)))
     (equal (greaterp x y)
	    (lessp y x))
     (equal (lesseqp x y)
	    (not (lessp y x)))
     (equal (greatereqp x y)
	    (not (lessp x y)))
     (equal (boolean x)
	    (or (equal x (t))
		(equal x (f))))
     (equal (iff x y)
	    (and (implies x y)
		 (implies y x)))
     (equal (even1 x)
	    (if (zerop x)
		(t)
	      (odd (sub1 x))))
     (equal (countps- l pred)
	    (countps-loop l pred (zero)))
     (equal (fact- i)
	    (fact-loop i 1))
     (equal (reverse- x)
	    (reverse-loop x (nil)))
     (equal (divides x y)
	    (zerop (remainder y x)))
     (equal (assume-true var alist)
	    (cons (cons var (t))
		  alist))
     (equal (assume-false var alist)
	    (cons (cons var (f))
		  alist))
     (equal (tautology-checker x)
	    (tautologyp (normalize x)
			(nil)))
     (equal (falsify x)
	    (falsify1 (normalize x)
		      (nil)))
     (equal (prime x)
	    (and (not (zerop x))
		 (not (equal x (add1 (zero))))
		 (prime1 x (sub1 x))))
     (equal (and p q)
	    (if p (if q (t)
		    (f))
	      (f)))
     (equal (or p q)
	    (if p (t)
	      (if q (t)
		(f))))
     (equal (not p)
	    (if p (f)
	      (t)))
     (equal (implies p q)
	    (if p (if q (t)
		    (f))
	      (t)))
     (equal (fix x)
	    (if (numberp x)
		x
	      (zero)))
     (equal (if (if a b c)
		d e)
	    (if a (if b d e)
	      (if c d e)))
     (equal (zerop x)
	    (or (equal x (zero))
		(not (numberp x))))
     (equal (plus (plus x y)
		  z)
	    (plus x (plus y z)))
     (equal (equal (plus a b)
		   (zero))
	    (and (zerop a)
		 (zerop b)))
     (equal (difference x x)
	    (zero))
     (equal (equal (plus a b)
		   (plus a c))
	    (equal (fix b)
		   (fix c)))
     (equal (equal (zero)
		   (difference x y))
	    (not (lessp y x)))
     (equal (equal x (difference x y))
	    (and (numberp x)
		 (or (equal x (zero))
		     (zerop y))))
     (equal (meaning (plus-tree (append x y))
		     a)
	    (plus (meaning (plus-tree x)
			   a)
		  (meaning (plus-tree y)
			   a)))
     (equal (meaning (plus-tree (plus-fringe x))
		     a)
	    (fix (meaning x a)))
     (equal (append (append x y)
		    z)
	    (append x (append y z)))
     (equal (reverse (append a b))
	    (append (reverse b)
		    (reverse a)))
     (equal (times x (plus y z))
	    (plus (times x y)
		  (times x z)))
     (equal (times (times x y)
		   z)
	    (times x (times y z)))
     (equal (equal (times x y)
		   (zero))
	    (or (zerop x)
		(zerop y)))
     (equal (exec (append x y)
		  pds envrn)
	    (exec y (exec x pds envrn)
		  envrn))
     (equal (mc-flatten x y)
	    (append (flatten x)
		    y))
     (equal (member x (append a b))
	    (or (member x a)
		(member x b)))
     (equal (member x (reverse y))
	    (member x y))
     (equal (length (reverse x))
	    (length x))
     (equal (member a (intersect b c))
	    (and (member a b)
		 (member a c)))
     (equal (nth (zero)
		 i)
	    (zero))
     (equal (exp i (plus j k))
	    (times (exp i j)
		   (exp i k)))
     (equal (exp i (times j k))
	    (exp (exp i j)
		 k))
     (equal (reverse-loop x y)
	    (append (reverse x)
		    y))
     (equal (reverse-loop x (nil))
	    (reverse x))
     (equal (count-list z (sort-lp x y))
	    (plus (count-list z x)
		  (count-list z y)))
     (equal (equal (append a b)
		   (append a c))
	    (equal b c))
     (equal (plus (remainder x y)
		  (times y (quotient x y)))
	    (fix x))
     (equal (power-eval (big-plus1 l i base)
			base)
	    (plus (power-eval l base)
		  i))
     (equal (power-eval (big-plus x y i base)
			base)
	    (plus i (plus (power-eval x base)
			  (power-eval y base))))
     (equal (remainder y 1)
	    (zero))
     (equal (lessp (remainder x y)
		   y)
	    (not (zerop y)))
     (equal (remainder x x)
	    (zero))
     (equal (lessp (quotient i j)
		   i)
	    (and (not (zerop i))
		 (or (zerop j)
		     (not (equal j 1)))))
     (equal (lessp (remainder x y)
		   x)
	    (and (not (zerop y))
		 (not (zerop x))
		 (not (lessp x y))))
     (equal (power-eval (power-rep i base)
			base)
	    (fix i))
     (equal (power-eval (big-plus (power-rep i base)
				  (power-rep j base)
				  (zero)
				  base)
			base)
	    (plus i j))
     (equal (gcd x y)
	    (gcd y x))
     (equal (nth (append a b)
		 i)
	    (append (nth a i)
		    (nth b (difference i (length a)))))
     (equal (difference (plus x y)
			x)
	    (fix y))
     (equal (difference (plus y x)
			x)
	    (fix y))
     (equal (difference (plus x y)
			(plus x z))
	    (difference y z))
     (equal (times x (difference c w))
	    (difference (times c x)
			(times w x)))
     (equal (remainder (times x z)
		       z)
	    (zero))
     (equal (difference (plus b (plus a c))
			a)
	    (plus b c))
     (equal (difference (add1 (plus y z))
			z)
	    (add1 y))
     (equal (lessp (plus x y)
		   (plus x z))
	    (lessp y z))
     (equal (lessp (times x z)
		   (times y z))
	    (and (not (zerop z))
		 (lessp x y)))
     (equal (lessp y (plus x y))
	    (not (zerop x)))
     (equal (gcd (times x z)
		 (times y z))
	    (times z (gcd x y)))
     (equal (value (normalize x)
		   a)
	    (value x a))
     (equal (equal (flatten x)
		   (cons y (nil)))
	    (and (nlistp x)
		 (equal x y)))
     (equal (listp (gopher x))
	    (listp x))
     (equal (samefringe x y)
	    (equal (flatten x)
		   (flatten y)))
     (equal (equal (greatest-factor x y)
		   (zero))
	    (and (or (zerop y)
		     (equal y 1))
		 (equal x (zero))))
     (equal (equal (greatest-factor x y)
		   1)
	    (equal x 1))
     (equal (numberp (greatest-factor x y))
	    (not (and (or (zerop y)
			  (equal y 1))
		      (not (numberp x)))))
     (equal (times-list (append x y))
	    (times (times-list x)
		   (times-list y)))
     (equal (prime-list (append x y))
	    (and (prime-list x)
		 (prime-list y)))
     (equal (equal z (times w z))
	    (and (numberp z)
		 (or (equal z (zero))
		     (equal w 1))))
     (equal (greatereqp x y)
	    (not (lessp x y)))
     (equal (equal x (times x y))
	    (or (equal x (zero))
		(and (numberp x)
		     (equal y 1))))
     (equal (remainder (times y x)
		       y)
	    (zero))
     (equal (equal (times a b)
		   1)
	    (and (not (equal a (zero)))
		 (not (equal b (zero)))
		 (numberp a)
		 (numberp b)
		 (equal (sub1 a)
			(zero))
		 (equal (sub1 b)
			(zero))))
     (equal (lessp (length (delete x l))
		   (length l))
	    (member x l))
     (equal (sort2 (delete x l))
	    (delete x (sort2 l)))
     (equal (dsort x)
	    (sort2 x))
     (equal (length (cons x1
			  (cons x2
				(cons x3 (cons x4
					       (cons x5
						     (cons x6 x7)))))))
	    (plus 6 (length x7)))
     (equal (difference (add1 (add1 x))
			2)
	    (fix x))
     (equal (quotient (plus x (plus x y))
		      2)
	    (plus x (quotient y 2)))
     (equal (sigma (zero)
		   i)
	    (quotient (times i (add1 i))
		      2))
     (equal (plus x (add1 y))
	    (if (numberp y)
		(add1 (plus x y))
	      (add1 x)))
     (equal (equal (difference x y)
		   (difference z y))
	    (if (lessp x y)
		(not (lessp y z))
	      (if (lessp z y)
		  (not (lessp y x))
		(equal (fix x)
		       (fix z)))))
     (equal (meaning (plus-tree (delete x y))
		     a)
	    (if (member x y)
		(difference (meaning (plus-tree y)
				     a)
			    (meaning x a))
	      (meaning (plus-tree y)
		       a)))
     (equal (times x (add1 y))
	    (if (numberp y)
		(plus x (times x y))
	      (fix x)))
     (equal (nth (nil)
		 i)
	    (if (zerop i)
		(nil)
	      (zero)))
     (equal (last (append a b))
	    (if (listp b)
		(last b)
	      (if (listp a)
		  (cons (car (last a))
			b)
		b)))
     (equal (equal (lessp x y)
		   z)
	    (if (lessp x y)
		(equal (t) z)
	      (equal (f) z)))
     (equal (assignment x (append a b))
	    (if (assignedp x a)
		(assignment x a)
	      (assignment x b)))
     (equal (car (gopher x))
	    (if (listp x)
		(car (flatten x))
	      (zero)))
     (equal (flatten (cdr (gopher x)))
	    (if (listp x)
		(cdr (flatten x))
	      (cons (zero)
		    (nil))))
     (equal (quotient (times y x)
		      y)
	    (if (zerop y)
		(zero)
	      (fix x)))
     (equal (get j (set i val mem))
	    (if (eqp j i)
		val
	      (get j mem))))))

(defun add-lemma-list (list)
  (mapc #'add-lemma list))

(defun add-lemma (term)
  (if (and (consp term)
	   (eq (car term) 'equal)
	   (consp (cadr term)))
      (setf (get (car (cadr term)) 'lemmas)
	   (cons
	    term
	    (get (car (cadr term)) 'lemmas)))
    (error "ADD-LEMMA did not like term:  " term)))

  ; Translates a term by replacing its constructor symbols by symbol-records.

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;
  ; The second phase.
  ;
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun test (n)
  (let ((term (apply-subst
	       '((x f (plus (plus a b)
			    (plus c (zero))))
		 (y f (times (times a b)
			     (plus c d)))
		 (z f (reverse (append (append a b)
				       (nil))))
		 (u equal (plus a b)
		    (difference x y))
		 (w lessp (remainder a b)
		    (member a (length b))))
	       (do ((term
		     '(implies (and (implies x y)
				    (and (implies y z)
					 (and (implies z u)
					      (implies u w))))
			       (implies x w))
		     `(or ,term (f)))
		    (n n (1- n)))
		   ((zerop n) term)))))
    (tautp term)))

(defun apply-subst (alist term)
  (if (not (consp term))
      (let ((temp-temp (assoc term alist)))
	(if temp-temp
	    (cdr temp-temp)
	  term))
    (cons (car term)
	  (apply-subst-list alist (cdr term)))))

(defun apply-subst-list (alist list)
  (map 'list (lambda (l)
	       (apply-subst alist l)) list))

(defun tautp (x)
  (tautologyp (rewrite x) '() '()))

(defun tautologyp (x true-list false-list)
  (cond ((truep x true-list)   't)
	((falsep x false-list) 'nil)
	((not (consp x)) 'nil)
	((eq (car x) 'if)
	 (cond ((truep (cadr x) true-list)
		(tautologyp (caddr x) true-list false-list))
	       ((falsep (cadr x) false-list)
		(tautologyp (cadddr x) true-list false-list))
	       (t (and (tautologyp (caddr x)
				   (cons (cadr x) true-list)
				   false-list)
		       (tautologyp (cadddr x)
				   true-list
				   (cons (cadr x) false-list))))))
	(t 'nil)))

(defvar *rewrite-count* 0) ; sanity check

  ; The next procedure is Henry Baker's sharing CONS, which avoids
  ; allocation if the result is already in hand.
  ; The REWRITE and REWRITE-ARGS procedures have been modified to
  ; use SCONS instead of CONS.

(defun scons (x y original)
  (if (and (eq x (car original))
	   (eq y (cdr original)))
      original
    (cons x y)))

(defun rewrite (term)
  (incf *rewrite-count*)
  (if (not (consp term))
      term
    (rewrite-with-lemmas (scons (car term)
				(rewrite-args (cdr term))
				term)
			 (get (car term) 'lemmas))))

(defun rewrite-args (list)
  (if (null list)
      '()
    (scons (rewrite (car list))
	   (rewrite-args (cdr list))
	   list)))

(defvar unify-subst '*)

(defun rewrite-with-lemmas (term list)
  (cond ((null list) term)
	((one-way-unify term (cadr (car list)))
	 (rewrite (apply-subst unify-subst (caddr (car list)))))
	(t (rewrite-with-lemmas term (cdr list)))))

(defun one-way-unify (term1 term2)
  (setq unify-subst '())
  (one-way-unify1 term1 term2))

(defun one-way-unify1 (term1 term2)
  (cond ((not (consp term2))
	 (let ((temp-temp (assoc term2 unify-subst)))
	   (cond (temp-temp
		  (term-equal? term1 (cdr temp-temp)))
		 ((numberp term2)	; This bug fix makes
		  (equal term1 term2)) ; nboyer 10-25% slower!
		 (t
		  (setq unify-subst (cons (cons term2 term1)
					  unify-subst))
		  't))))
	((not (consp term1)) 'nil)
	((eq (car term1)
	     (car term2))
	 (one-way-unify1-list (cdr term1)
			      (cdr term2)))
	(t 'nil)))

(defun one-way-unify1-list (list1 list2)
  (cond ((null list1) (null list2))
	((null list2) 'nil)
	((one-way-unify1 (car list1) (car list2))
	 (one-way-unify1-list (cdr list1) (cdr list2)))
	(t 'nil)))

(defvar false-term '(f))
(defvar true-term '(t))

(defun falsep (x list)
  (or (term-equal? x false-term)
      (term-member? x list)))

(defun truep (x list)
  (or (term-equal? x true-term)
      (term-member? x list)))

(defun term-equal? (x y)
  (if (consp x)
      (and (consp y)
	   (eq (car x) (car y))
	   (term-args-equal? (cdr x) (cdr y)))
    (equal x y)))

(defun term-args-equal? (list1 list2)
  (cond ((null list1) (null list2))
	((null list2) 'nil)
	((term-equal? (car list1) (car list2))
	 (term-args-equal? (cdr list1) (cdr list2)))
	(t 'nil)))

(defun term-member? (x list)
  (member x list :test #'term-equal?))

(defun test-boyer (n)
  (setq *rewrite-count* 0)
  (let ((answer (test n)))
    (format t "~&~s" *rewrite-count*)
    answer))



-- 
~jrm
From: Kenny Tilton
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <Eq5Bc.129139$Nn4.27865424@twister.nyc.rr.com>
Joe Marshall wrote:

> Antonio Menezes Leitao <··············@evaluator.pt> writes:
> 
> 
>>We must be talking about different programs.  I can't get those results in
>>CMUCL.  Can you send me the exact program that produced those results?
> 
> 
> I just tested this, and it produces the expected results.  It corrects
> the typo from before and re-orders the false-term and true-term
> definitions to avoid a warning, but is otherwise unchanged.  Did you
> run SETUP prior to running TEST?  You'd get really screwy results if
> you did not.
> 
> It would be interesting to see how this would do if it were written in
> Java with an eye to how a Java weenie would do it:

Yeah, in all seriousness I am thinking this could be a fun parallel to 
those cll exercises in which someone charges in with some benchmark 
comparing C and Lisp and a few days later the Lisp gurus have matched 
the C performance.

Run that same exercise on cljava in a lisp-java standoff just to see 
what falls out. Could be some interesting java, or maybe a better 
benchmark. doesn't matter, should be fun.

kenny

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Dmitry Kim
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <20040616214357.41e36424@jsn.nichego.net>
	hi,

On Wed, 16 Jun 2004 13:17:04 -0400 Joe Marshall <···@ccs.neu.edu> wrote:
>
> Never mind the Lisp code.  The `benchmarks' are useless and the
> methodology sucks.  How often do you need to pipe the result of
> Ackermann's function to the shell *really* fast?

did you really read either benchmark methodology paper or cmucl
ackermann test source code? the value of ackermann function is only
printed *once*, and it doesn't contribute much to overall time anyway.
you don't need to pipe anything "*really* fast" for that.
anyway, all benchmark suck, but this one just doesn't suck *that* bad.

-jsn.

RIPE nic-handle: JSN7-RIPE, email address: jason [AT] nichego [.] net
From: Joe Marshall
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <7ju7qn0n.fsf@ccs.neu.edu>
Dmitry Kim <·····@redline.ru> writes:

> 	hi,
>
> On Wed, 16 Jun 2004 13:17:04 -0400 Joe Marshall <···@ccs.neu.edu> wrote:
>>
>> Never mind the Lisp code.  The `benchmarks' are useless and the
>> methodology sucks.  How often do you need to pipe the result of
>> Ackermann's function to the shell *really* fast?
>
> did you really read either benchmark methodology paper or cmucl
> ackermann test source code? 

Yes.

> the value of ackermann function is only printed *once*, and it
> doesn't contribute much to overall time anyway.

I was caricaturing.  Look at `hash access'.  Nominally, it is testing
hash tables, but the code appears to be doing more along the lines of
testing integer->string conversion and printing speed.

`Hello World' is a benchmark?  Of what?

> you don't need to pipe anything "*really* fast" for that.
> anyway, all benchmark suck, but this one just doesn't suck *that* bad.

There are several reasons the methodology sucks.

  - The times are reported to the nearest .01 seconds no matter how
    fast the process completed, so there is far less information about
    the better performing implementations.

  - Reporting absolute time rather than the logarithm of the time or
    the ratio of times penalizes the slower performing
    implementations.

  - Linear listing of the languages bears no relation to relative
    performance:  a language might be near the bottom because it truly
    sucks (see Java2 on String concatenation), or it might be near the
    bottom because it is only slightly slower than the others (see
    `hash access')
From: Dmitry Kim
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <20040617010505.405b89c7@jsn.nichego.net>
	hi,

On Wed, 16 Jun 2004 16:13:44 -0400 Joe Marshall <···@ccs.neu.edu> wrote:
> > the value of ackermann function is only printed *once*, and it
> > doesn't contribute much to overall time anyway.
> 
> I was caricaturing.  Look at `hash access'.  Nominally, it is testing
> hash tables, but the code appears to be doing more along the lines of
> testing integer->string conversion and printing speed.
> 
> `Hello World' is a benchmark?  Of what?

of startup latency, obviously. it matters, sometimes. and as i said
before, i also would like to see (at least some) shootout tests *not*
measuring latency times.

> There are several reasons the methodology sucks.
> 
>   - The times are reported to the nearest .01 seconds no matter how
>     fast the process completed, so there is far less information about
>     the better performing implementations.

there are two different issues about 0.01 seconds cpu time:
1) startup/exit latency part is too big (and i was mentioning it when
talking about "latency vs throughtput" issue), and
2) low timer resolution probably adds a noticeable amount of noise to
test results.

in general, i agree -- 0.01 seconds tests are bad. OTOH, if, for
example, sablevm is almost 4000 times slower than mlton on "exceptions"
test, and we re-write the test to achive 1 second cpu time for mlton ...

>   - Reporting absolute time rather than the logarithm of the time or
>     the ratio of times penalizes the slower performing
>     implementations.

could you please explain this one?

>   - Linear listing of the languages bears no relation to relative
>     performance:  a language might be near the bottom because it truly
>     sucks (see Java2 on String concatenation), or it might be near the
>     bottom because it is only slightly slower than the others (see
>     `hash access')

well, you still have resulting numbers for cpu time and all, right? it's
absolutely not about the methodology, it's about the visual
representation. you still have to order the list in some way, you know.
they also got an image with plotted data, btw -- for those who don't
like the sorting order.


-jsn.

RIPE nic-handle: JSN7-RIPE, email address: jason [AT] nichego [.] net
From: Joe Marshall
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <oendxztm.fsf@comcast.net>
Dmitry Kim <·····@redline.ru> writes:

>>   - Reporting absolute time rather than the logarithm of the time or
>>     the ratio of times penalizes the slower performing
>>     implementations.
>
> could you please explain this one?

Sorry about taking so long to reply to this one.

Suppose we were comparing three implementations.  Implementation A
runs the benchmark in 2.15 seconds, implementation B in 4.8 seconds,
and implementation C in 10.7 seconds.  Clearly implementation C is
terrible:  B is only about 2.6 seconds slower, but C is more than 8
seconds slower.

But look again...

B is a factor of 2.23 slower than A
C is a factor of 2.3 slower than B

The improvement of going from implementation C to implementation B is
no better than the improvement going from implementation B to
implementation A.

This can be more easily seen if we report the log of the time:

  A  0.77
  B  1.6
  C  2.4  

These logs are pretty evenly spaced which reflects that there is a
uniform gain in performance as you go through the implementations.

As it turns out, the human senses of sight and hearing work on log
scale with the smallest perceptable difference being about 10 times
the log-base-ten of the values.  

So for a benchmark such as the Regular Expression Matching, 

    system  time     10 log 10 time

    ghc     0.01   -20.0
    mlton   0.36   -4.44
    cmucl   1.16    0.64
    icon    1.46    1.64
    mawk    1.52    1.82
    pike    1.62    2.10
    ocaml   1.67    2.23
    perl    1.93    2.86
    gcc     1.94    2.88
    ocamlb  1.95    2.90
    python  2.32    3.65
    smlnj   2.78    4.44
    lua     3.05    4.84
    rep     3.92    5.93
    ruby    6.12    7.87
    gawk    7.92    8.99
    tcl    10.66    10.28
    gforth 10.88    10.37
    guile  11.02    10.42
    erlang 22.96    13.61
    hipe   28.74    15.88

In the third column, a difference of 3 is about a factor of 2, a
difference of less than one will be hard to notice.


-- 
~jrm
From: Dmitry Kim
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <20040621101925.0c83c47f@jsn.nichego.net>
	hi,

On Mon, 21 Jun 2004 05:09:19 GMT Joe Marshall
<·············@comcast.net> wrote:
> As it turns out, the human senses of sight and hearing work on log
> scale with the smallest perceptable difference being about 10 times
> the log-base-ten of the values.  

aha, i see. so we're still talking about a better way to represent the
(same) benchmark results. it's not about testing methodology, it's
rather about analysis methodology. but is it really a problem? we are
presented with raw test results, with (almost) no analysis given -- and
to me, it's much better than otherwise.

it's really a matter of perception, but i do prefer to see absolute [not
log10()-ed] numbers in result table -- for me, dividing 2.32 seconds
(python) by 1.16 seconds (cmucl) is a natural way to compare the speed
of two implementations. otoh, i think it would be nice to have a
logarithmic scale on graph.

if we switch to log10()-ed CPU times in scorecard page, it would be a
loss of functionality. the same applies to log10()-ed loc and memory
footprint. thus, all we can do is to add a logarithmic scale to
graph charts and add another column to the printed results table, just
like this:

> So for a benchmark such as the Regular Expression Matching, 
> 
>     system  time     10 log 10 time
> 
>     ghc     0.01   -20.0
>     mlton   0.36   -4.44
>     cmucl   1.16    0.64
>     icon    1.46    1.64
>     mawk    1.52    1.82
>     pike    1.62    2.10
>     ocaml   1.67    2.23
>     perl    1.93    2.86
>     gcc     1.94    2.88
>     ocamlb  1.95    2.90
>     python  2.32    3.65
>     smlnj   2.78    4.44
>     lua     3.05    4.84
>     rep     3.92    5.93
>     ruby    6.12    7.87
>     gawk    7.92    8.99
>     tcl    10.66    10.28
>     gforth 10.88    10.37
>     guile  11.02    10.42
>     erlang 22.96    13.61
>     hipe   28.74    15.88

well, of course it is an improvement, but sorry, i don't see nothing
revolutionary about it. actually, it's not "the benchmark methodology
sucks", it's "the benchmark report pages can be somewhat improved".
(the methodology still sucks on "latency vs. throughput" side, but
everybody seems to all agree on that, including the benchmark
maintainer).

-jsn.

RIPE nic-handle: JSN7-RIPE, email address: jason [AT] nichego [.] net
From: Joe Marshall
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <d63rlo56.fsf@ccs.neu.edu>
Dmitry Kim <·····@redline.ru> writes:

> 	hi,
>
> On Mon, 21 Jun 2004 05:09:19 GMT Joe Marshall
> <·············@comcast.net> wrote:
>> As it turns out, the human senses of sight and hearing work on log
>> scale with the smallest perceptable difference being about 10 times
>> the log-base-ten of the values.  
>
> aha, i see. so we're still talking about a better way to represent the
> (same) benchmark results. it's not about testing methodology, it's
> rather about analysis methodology. but is it really a problem? we are
> presented with raw test results, with (almost) no analysis given -- and
> to me, it's much better than otherwise.

Just raw test results is certainly better than raw results with a bad
analysis, but a large number of people are not going to go through the
effort of interpreting the raw results.  A good interpretation *with*
the raw results for those that are interested would be ideal.

> well, of course it [presentation of the logarithm of the data] is an
> improvement, but sorry, i don't see nothing revolutionary about it.

It isn't revolutionary at all, it's retro.  I think it was a good idea
that seems to have been forgotten.
From: Dave Fayram
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <38ff3d6c.0406161034.26009273@posting.google.com>
Dmitry Kim <·····@redline.ru> wrote in message news:<·······················@jsn.nichego.net>...

> did you see "The Great Computer Language Shootout"? the project was
> revived recently at http://shootout.alioth.debian.org.
> they don't do no closed-source language implementation, but cmucl and
> emacs lisp are on the list, as well as several scheme implementations.
> 

This is not just for our edification, honestly. This is kind of a
piggyback media event. :)

But what I'd *really* like to show is a progression. Take the
fibbonaci function. Implement it. Then, doing the minimum amount of
work for your language, add tracing. Then add memoization. Trace the
speed, size, and percent difference along the way.

Part of the reason Java does so well there is because Java's JIT stuff
kind of knows about functions that match the fibbonaci pattern and can
explicitly optimize them. By adding more complex (real world)
functionality to a trivially academic system like that, and showing
how much of an advantage Lisp offers over Java for work like this (and
how well it holds up in performance), we get a lot of positive press
on a big forum.

I've also got someone who will do this with Java, and another for
Python. C++ is easy to find.

So I reiterate, if there are any people who would like to do the lisp
part of this, please email me. I am going to set it up and I've gotten
permission to run the tests on Dual Xeon workstations, so I can do the
tests and even the presentation. All I need are coders who are willing
to be prompt and to set up the right environment.

This is just anoter way to get Lisp into mainstream press. I'm not
saying it's original.
From: Dmitry Kim
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <20040617000401.02db1d64@jsn.nichego.net>
	hi,

On 16 Jun 2004 11:34:26 -0700 ·········@lensmen.net (Dave Fayram) wrote:
> This is not just for our edification, honestly. This is kind of a
> piggyback media event. :)
> But what I'd *really* like to show is a progression. Take the
> fibbonaci function. Implement it. Then, doing the minimum amount of
> work for your language, add tracing. Then add memoization. Trace the
> speed, size, and percent difference along the way.

well, i may be wrong, but imho you don't make media events like that. do
it as a progression, and you'll get yet another lisp tutorial -- and
tutorials don't get much press. they are too complicated or something.

> Part of the reason Java does so well there is because Java's JIT stuff
> kind of knows about functions that match the fibbonaci pattern and can
> explicitly optimize them.

umm hmm. where exactly is java doing well? on the shootout scorecard
java is slower than cmucl [yes, i know, all benchmark suck :)]. java
(usually) has a huge memory footprint, etc.
well, probably what you mean is "java is doing well in the market and/or
in press". yes, but imho it's not because java is such a nice language,
but because sun has such a nice and mighty marketing department. i
mean, it's relatively easy to construct a benchmark to show that the
language X is the best of all (for any reasonable given X), but it takes
both money and efforts to put this benchmark result sheet into every
IT manager's mailbox. java is also successfully assimilating C/C++
programmers population, which is easy since java is just a"somewhat
fixed" C++.
unfortunately, i don't see how just any of the mentioned above
strategies can be implemented for lisp.
basically, i think we can't just do what big companies do, because we
have no money to waste and no established brand to use. probably we
should learn from successful public domain languages, not from java.
something like ruby or python -- they started late, but their market
share is noticeable and still climbing.

> So I reiterate, if there are any people who would like to do the lisp
> part of this, please email me. I am going to set it up and I've gotten
> permission to run the tests on Dual Xeon workstations, so I can do the
> tests and even the presentation. All I need are coders who are willing
> to be prompt and to set up the right environment.

btw, in spite of all i said above, i'd like to help, but i have almost
no experience in real-life lisp coding. a newbie, you know.

-jsn.

RIPE nic-handle: JSN7-RIPE, email address: jason [AT] nichego [.] net
From: André Thieme
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <caqcm7$md6$1@ulric.tng.de>
Dmitry Kim schrieb:

> well, probably what you mean is "java is doing well in the market and/or
> in press". yes, but imho it's not because java is such a nice language,
> but because sun has such a nice and mighty marketing department.

I think it also lies in the language Java itself. It is very well 
designed for the average programmer. It has everything they love and not 
to much, of what could confuse the average programmer.
Don't forget, Java was designed by a Lisper and there is one person 
working at Sun who is currently having a /very/ big influence on the 
language: Guy Steele.

They are very experienced in language design and managed (okay, with 
help of money and marketing in the background) to create a language that 
really has what the mass market wants.

A one year old interview, not really regarding this topic, but some 
might be interested anyways:
http://java.sun.com/features/2003/05/steele_qa.html


Andr�
--
From: Dmitry Kim
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <20040617015034.01b2fd8c@jsn.nichego.net>
	hi,

On Wed, 16 Jun 2004 23:07:50 +0200 Andr_ Thieme  
<······························@justmail.de> wrote:
> I think it also lies in the language Java itself. It is very well 
> designed for the average programmer. It has everything they love and
> not to much, of what could confuse the average programmer.

yes, i agree. actually, java is designed for big corporate guys, to let
them hire 100 average programmers and write down a formal
desogn contract for every single one of them, before the first line of
code is produced. [look, i'm almost quoting paul graham!]
and btw, let's face it, it's the way 90% of big software projects are
written these days. is there really a big niche for lisp in this brave
new world?
imho, lisp is just too nice for the mass market. damn, even unix seems
to be too nice for the mass market.

obligatory references:
http://www.paulgraham.com/icad.html Paul Graham, Revenge of the Nerds
http://dreamsongs.com/WIB.html Richard P. Gabriel, Lisp: Good News, Bad
News, How to Win Big

-jsn.

RIPE nic-handle: JSN7-RIPE, email address: jason [AT] nichego [.] net
From: striker
Subject: Re: Lisp vs. Java vs. C++ speed comparison time?
Date: 
Message-ID: <29bcd2fa57c94a29a8794d591a2eda77@localhost.talkaboutprogramming.com>
I have some P4 3g machines I could help do stuff with.
Just let me know how and off we go.
Im very interested in the results.
Regs striker.