May 11, 2015 Re: D looses in speed to Common Lisp | ||||
|---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Monday, 11 May 2015 at 22:22:23 UTC, anonymous wrote: > On Monday, 11 May 2015 at 21:15:33 UTC, Dzhon Smit wrote: >> Tests on my machine: >> [code]$ time ./fib >> 0 >> >> real 0m6.458s >> user 0m2.250s >> sys 0m0.933s >> $ time sbcl --dynamic-space-size 4GB --script fib.lisp >> 0 >> >> real 0m1.884s >> user 0m1.290s >> sys 0m0.260s[/code] > > Can't confirm that. Times for me (linux x86_64): > > ---- > $ dmd fib.d && time ./fib > 0 > > real 0m2.410s > user 0m1.844s > sys 0m0.558s > > $ time sbcl --dynamic-space-size 4GB --script fib.lisp > 0 > > real 0m2.659s > user 0m2.144s > sys 0m0.506s > ---- > > As usual, ldc produces a faster binary than dmd: > > ---- > $ ldc2 fib.d && time ./fib > 0 > > real 0m1.900s > user 0m1.396s > sys 0m0.499s > ---- > > Optimization flags don't seem to matter much for this program. Could you re-run sbcl? The first time it runs it creates fasls, and afterwards it reuses them. Probably you shouldn't include the compile time for dmd either. > import std.stdio, std.bigint; > import std.range; > import std.algorithm; > > void main() { > > int n = 100000; > auto sumFib1 = recurrence!("a[n-1] + a[n-2]")(BigInt(0), > BigInt(1)).take(n).sum; > auto sumFib2 = recurrence!("a[n-1] + a[n-2]")(BigInt(0), > BigInt(1)).take(n).sum; > > writeln(sumFib2 - sumFib1); // 0 > } The point was to compare the performance of nearly identical pieces of code in D and in CL. However, when I compile this idiomatic sample with `dmd fib2`, I get $ time ./fib2 0 real 0m2.226s user 0m2.223s sys 0m0.003s which is still slower. | |||
May 12, 2015 Re: D looses in speed to Common Lisp | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dzhon Smit | On Monday, 11 May 2015 at 23:32:48 UTC, Dzhon Smit wrote:
> The point was to compare the performance of nearly identical pieces of code in D and in CL. However, when I compile this idiomatic sample with `dmd fib2`, I get
>
> $ time ./fib2
> 0
>
> real 0m2.226s
> user 0m2.223s
> sys 0m0.003s
>
> which is still slower.
we already know dmd doesn't produce the fastest code, and obviously you are not comparing languages but a complex set of things particularly compilers. nobody who cares about performance will stick with dmd without trying alternatives (and these are free, readily available alternatives not special things you need to pay a fortune for as with some of the 'java GC can be realtime' guys argued indicated as having relevance to the commercial choice in ordinary circumstances to use java or not).
if one wanted to spend a couple hundred k bucks on rewriting the codegen, I am sure you would see dmd fast again, but what would that demonstrate about D the language?
it's fair play to compare naive code using fast compilers, but just like micro benchmarks, one shouldn't make more of the result than may be justified. ie the real question is in practical use cases (bearing in mind you are going to pick one or two languages and stick with them, figuring out the tricks with experience), given reasonable effort, what is relative performance like? and I doubt anyone is going to not use D because "it's slower than common lisp".
what I have read of the facebook experience (although hardly a controlled experiment by a neutral observer) is intriguing from that perspective.
| |||
May 12, 2015 Re: D looses in speed to Common Lisp | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Laeeth Isharc | On Tuesday, 12 May 2015 at 01:20:13 UTC, Laeeth Isharc wrote:
> On Monday, 11 May 2015 at 23:32:48 UTC, Dzhon Smit wrote:
>
>> The point was to compare the performance of nearly identical pieces of code in D and in CL. However, when I compile this idiomatic sample with `dmd fib2`, I get
>>
>> $ time ./fib2
>> 0
>>
>> real 0m2.226s
>> user 0m2.223s
>> sys 0m0.003s
>>
>> which is still slower.
ie, especially post internet, one has a responsibility for the effect one's words have on the world because they will be read by potentially many people that don't have the context to hand and take things literally.
| |||
May 12, 2015 Re: D looses in speed to Common Lisp | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dzhon Smit | On Monday, 11 May 2015 at 21:15:33 UTC, Dzhon Smit wrote: Seems this: --dynamic-space-size 4GB is pretty important. I don't have that much RAM on my Chromebook so I removed it. It dies quickly with the error Heap exhausted during garbage collection: 1408 bytes available, 2240 requested. I'm guessing that your code is not doing the same thing as the D code if you have to use tricks like that just to get it to run. Having used Common Lisp, I know your program requires extensive knowledge of the language, and was the result of a careful optimization exercise - unlike the D code. It's definitely not the kind of code you'd write after reading Practical Common Lisp. | |||
May 12, 2015 Re: D looses in speed to Common Lisp | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dzhon Smit |
On Mon, 11 May 2015 23:32:47 +0000
Dzhon Smit via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On Monday, 11 May 2015 at 22:22:23 UTC, anonymous wrote:
> > On Monday, 11 May 2015 at 21:15:33 UTC, Dzhon Smit wrote:
> >> Tests on my machine:
> >> [code]$ time ./fib
> >> 0
> >>
> >> real 0m6.458s
> >> user 0m2.250s
> >> sys 0m0.933s
> >> $ time sbcl --dynamic-space-size 4GB --script fib.lisp
> >> 0
> >>
> >> real 0m1.884s
> >> user 0m1.290s
> >> sys 0m0.260s[/code]
> >
> > Can't confirm that. Times for me (linux x86_64):
> >
> > ----
> > $ dmd fib.d && time ./fib
> > 0
> >
> > real 0m2.410s
> > user 0m1.844s
> > sys 0m0.558s
> >
> > $ time sbcl --dynamic-space-size 4GB --script fib.lisp
> > 0
> >
> > real 0m2.659s
> > user 0m2.144s
> > sys 0m0.506s
> > ----
> >
> > As usual, ldc produces a faster binary than dmd:
> >
> > ----
> > $ ldc2 fib.d && time ./fib
> > 0
> >
> > real 0m1.900s
> > user 0m1.396s
> > sys 0m0.499s
> > ----
> >
> > Optimization flags don't seem to matter much for this program.
>
> Could you re-run sbcl? The first time it runs it creates fasls, and afterwards it reuses them. Probably you shouldn't include the compile time for dmd either.
>
> > import std.stdio, std.bigint;
> > import std.range;
> > import std.algorithm;
> >
> > void main() {
> >
> > int n = 100000;
> > auto sumFib1 = recurrence!("a[n-1] + a[n-2]")(BigInt(0),
> > BigInt(1)).take(n).sum;
> > auto sumFib2 = recurrence!("a[n-1] + a[n-2]")(BigInt(0),
> > BigInt(1)).take(n).sum;
> >
> > writeln(sumFib2 - sumFib1); // 0
> > }
>
> The point was to compare the performance of nearly identical pieces of code in D and in CL. However, when I compile this idiomatic sample with `dmd fib2`, I get
>
> $ time ./fib2
> 0
>
> real 0m2.226s
> user 0m2.223s
> sys 0m0.003s
>
> which is still slower.
This is wierd, you probably enable debug or I do not belive your timing. Even with dmd (not ldc or gdc) I get better timing for D idiomatic code than lisp version.
$ time sbcl --dynamic-space-size 4GB --script fib.lisp
0
real 0m2.263s
user 0m1.337s
sys 0m0.917s
[kozak@dajinka ~]$ dmd test.d
[kozak@dajinka ~]$ time ./test
0
real 0m1.883s
user 0m1.873s
sys 0m0.003s
[kozak@dajinka ~]$ ldc test.d
[kozak@dajinka ~]$ time ./test
0
real 0m1.311s
user 0m1.310s
sys 0m0.000s
[kozak@dajinka ~]$ gdc -o test test.d
[kozak@dajinka ~]$ time ./test
0
real 0m1.447s
user 0m1.440s
sys 0m0.003s
[kozak@dajinka ~]$ dmd -debug test.d
[kozak@dajinka ~]$ time ./test
0
real 0m3.816s
user 0m3.797s
sys 0m0.010s
| |||
May 12, 2015 Re: D looses in speed to Common Lisp | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bachmeier | On Tuesday, 12 May 2015 at 01:48:58 UTC, bachmeier wrote:
> On Monday, 11 May 2015 at 21:15:33 UTC, Dzhon Smit wrote:
>
> Seems this:
>
> --dynamic-space-size 4GB
>
> is pretty important. I don't have that much RAM on my Chromebook so I removed it. It dies quickly with the error
>
> Heap exhausted during garbage collection: 1408 bytes available, 2240 requested.
>
> I'm guessing that your code is not doing the same thing as the D code if you have to use tricks like that just to get it to run. Having used Common Lisp, I know your program requires extensive knowledge of the language, and was the result of a careful optimization exercise - unlike the D code. It's definitely not the kind of code you'd write after reading Practical Common Lisp.
Thanks for this bit of information.
| |||
May 12, 2015 Re: D looses in speed to Common Lisp | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dzhon Smit | On Monday, 11 May 2015 at 23:32:48 UTC, Dzhon Smit wrote:
> Could you re-run sbcl? The first time it runs it creates fasls, and afterwards it reuses them. Probably you shouldn't include the compile time for dmd either.
Sure thing. I think that wasn't the first run already. But to make sure, I just ran it all again. The D version here is the original you posted.
----
$ time sbcl --dynamic-space-size 4GB --script fib.lisp
0
real 0m3.181s
user 0m1.814s
sys 0m0.459s
$ time sbcl --dynamic-space-size 4GB --script fib.lisp
0
real 0m2.256s
user 0m1.828s
sys 0m0.423s
$ dmd fib.d && time ./fib
0
real 0m2.227s
user 0m1.714s
sys 0m0.507s
$ ldc2 fib.d && time ./fib
0
real 0m1.688s
user 0m1.341s
sys 0m0.343s
----
| |||
May 12, 2015 Re: D looses in speed to Common Lisp | ||||
|---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Monday, 11 May 2015 at 22:22:23 UTC, anonymous wrote:
> Optimization flags don't seem to matter much for this program.
Most of the bigint work is probably happening in handwritten assembly code and the memory allocation code is compiled in to druntime, so the optimiser isn't really getting much important to work on.
| |||
May 12, 2015 Re: D looses in speed to Common Lisp | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bachmeier | Am Tue, 12 May 2015 01:48:57 +0000 schrieb "bachmeier" <no@spam.net>: > On Monday, 11 May 2015 at 21:15:33 UTC, Dzhon Smit wrote: > > Seems this: > > --dynamic-space-size 4GB > > is pretty important. I don't have that much RAM on my Chromebook so I removed it. It dies quickly with the error > > Heap exhausted during garbage collection: 1408 bytes available, 2240 requested. > > I'm guessing that your code is not doing the same thing as the D code if you have to use tricks like that just to get it to run. Having used Common Lisp, I know your program requires extensive knowledge of the language, and was the result of a careful optimization exercise - unlike the D code. It's definitely not the kind of code you'd write after reading Practical Common Lisp. I don't know LISP, but I find no trace of appending numbers to a temporary dynamic array in the LISP code. If so, from an algorithmic point of view Daniel Kozak's version is the most spot-on translation of the original. The idea behind porting code between languages as different as D and LISP should not be to replicate the computational work while staying true to the target language. Similar looks wont get you there. -- Marco | |||
May 12, 2015 Re: D looses in speed to Common Lisp | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Marco Leise | On Tuesday, 12 May 2015 at 10:03:16 UTC, Marco Leise wrote:
> Am Tue, 12 May 2015 01:48:57 +0000
> schrieb "bachmeier" <no@spam.net>:
>
>> On Monday, 11 May 2015 at 21:15:33 UTC, Dzhon Smit wrote:
>>
>> Seems this:
>>
>> --dynamic-space-size 4GB
>>
>> is pretty important. I don't have that much RAM on my Chromebook so I removed it. It dies quickly with the error
>>
>> Heap exhausted during garbage collection: 1408 bytes available, 2240 requested.
>>
>> I'm guessing that your code is not doing the same thing as the D code if you have to use tricks like that just to get it to run. Having used Common Lisp, I know your program requires extensive knowledge of the language, and was the result of a careful optimization exercise - unlike the D code. It's definitely not the kind of code you'd write after reading Practical Common Lisp.
>
> I don't know LISP, but I find no trace of appending numbers to
> a temporary dynamic array in the LISP code. If so, from an
> algorithmic point of view Daniel Kozak's version is the most
> spot-on translation of the original.
>
> The idea behind porting code between languages as different as
> D and LISP should not be to replicate the computational work
> while staying true to the target language. Similar looks wont
> get you there.
The main point in posting that was to show that the program
doesn't even run without an SBCL-specific command line option.
I'm not going to dig into this because it's a silly example.
However, my guess is that it has to do with this:
(fib '() (cons last fib))
That creates a new cons each time through. Reserving 4 GB
probably allows the program to avoid the garbage collector.
I'm assuming that the other part of the performance story is this:
(loop :for e :in fib2 :sum e)
where the sum is almost certainly optimized, so the benchmark
doesn't measure the speed of CL anyway, only the ability of the
SBCL compiler developers to write optimized code that covers a
handful of common cases.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply