Jump to page: 1 2 3
Thread overview
Dynamic Closure + Lazy Arguments = Performance Killer?
Oct 24, 2008
Jason House
Oct 24, 2008
Gregor Richards
Oct 24, 2008
Jason House
Oct 24, 2008
Frank Benoit
Oct 24, 2008
Bill Baxter
Oct 24, 2008
Robert Fraser
Oct 24, 2008
bearophile
Oct 25, 2008
Jason House
Oct 25, 2008
bearophile
Oct 25, 2008
Jason House
Oct 25, 2008
Bill Baxter
Oct 25, 2008
Jason House
Oct 25, 2008
Lars Ivar Igesund
Oct 25, 2008
Denis Koroskin
Oct 25, 2008
Lars Ivar Igesund
Oct 25, 2008
Frits van Bommel
Oct 25, 2008
Denis Koroskin
Oct 26, 2008
Bill Baxter
Oct 25, 2008
Bill Baxter
Oct 25, 2008
Jason House
Oct 25, 2008
Jason House
Elegant syntax for dynamic vs. static delegates
Nov 03, 2008
Russell Lewis
October 24, 2008
I ported some monte carlo simulation code from Java to D2, and performance is horrible.

34% of the execution time is used by std.random.uniform. To my great surprise, 25% of the execution  time is memory allocation (and collection) from that random call. The only candidate source I see is a call to ensure with lazy arguments. The memory allocation occurs at the start of the UniformDistribution call. I assume this is dynamic closure kicking in.

Can anyone verify that this is the case?

600000 memory allocations per second really kills performance!
October 24, 2008
Jason House wrote:
> I ported some monte carlo simulation code from Java to D2, and performance is horrible.
> 
> 34% of the execution time is used by std.random.uniform. To my great surprise, 25% of the execution  time is memory allocation (and collection) from that random call. The only candidate source I see is a call to ensure with lazy arguments. The memory allocation occurs at the start of the UniformDistribution call. I assume this is dynamic closure kicking in.
> 
> Can anyone verify that this is the case?
> 
> 600000 memory allocations per second really kills performance!

Java has a much better garbage collector than D, as it doesn't need to be conservative.

 - Gregor Richards
October 24, 2008
Gregor Richards Wrote:

> Jason House wrote:
> > I ported some monte carlo simulation code from Java to D2, and performance is horrible.
> > 
> > 34% of the execution time is used by std.random.uniform. To my great surprise, 25% of the execution  time is memory allocation (and collection) from that random call. The only candidate source I see is a call to ensure with lazy arguments. The memory allocation occurs at the start of the UniformDistribution call. I assume this is dynamic closure kicking in.
> > 
> > Can anyone verify that this is the case?
> > 
> > 600000 memory allocations per second really kills performance!
> 
> Java has a much better garbage collector than D, as it doesn't need to be conservative.
> 
>   - Gregor Richards

The code is written to explicitly avoid memory allocation, especially in tight loops. Without this dynamic closure, the garbage collecor would never run. This case is especially pathetic since the call to ensure will never trigger.

This is part of a mini language shootout. The Java version I cloned runs 4x faster. This is only one piece of a much bigger problem.
October 24, 2008
Jason House schrieb:
> I ported some monte carlo simulation code from Java to D2, and performance is horrible.
> 
> 34% of the execution time is used by std.random.uniform. To my great surprise, 25% of the execution  time is memory allocation (and collection) from that random call. The only candidate source I see is a call to ensure with lazy arguments. The memory allocation occurs at the start of the UniformDistribution call. I assume this is dynamic closure kicking in.
> 
> Can anyone verify that this is the case?
> 
> 600000 memory allocations per second really kills performance!

It was written in this NG over and over. The D2 full closure feature is a BIG!!!! problem.

The nested functions passed as callback are an important and performance technique in D. The D2 full closure "feature" effectively removes it and makes D2 less attractive IMHO.
October 24, 2008
Jason House:

> 34% of the execution time is used by std.random.uniform.

Kiss of Tango is much faster, and there's a much faster still (but good still) rnd generator around...


> Can anyone verify that this is the case?

Can you show us a working minimal code I/we can test?

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

Frank Benoit:

>The D2 full closure "feature" effectively removes it and makes D2 less attractive IMHO.<

The first simple solution is to add the possibility of adding "scope" to closures to not use the heap (but I don't know how to do that in every situation, and it makes the already long syntax of lambdas even longer).

But the probably best way for D to become more functional (and normal functional programming is often full of functions that move everywhere, often they are closures, but only virtually) is to grow some more optimizing capabilities, so closures aren't a problem anymore. There are many ways to perform such optimizations (but in a language mostly based on side effects it's less easy).

Bye,
bearophile
October 24, 2008
On Sat, Oct 25, 2008 at 7:23 AM, Frank Benoit <keinfarbton@googlemail.com> wrote:
> Jason House schrieb:
>> I ported some monte carlo simulation code from Java to D2, and performance is horrible.
>>
>> 34% of the execution time is used by std.random.uniform. To my great surprise, 25% of the execution  time is memory allocation (and collection) from that random call. The only candidate source I see is a call to ensure with lazy arguments. The memory allocation occurs at the start of the UniformDistribution call. I assume this is dynamic closure kicking in.
>>
>> Can anyone verify that this is the case?
>>
>> 600000 memory allocations per second really kills performance!
>
> It was written in this NG over and over. The D2 full closure feature is a BIG!!!! problem.
>
> The nested functions passed as callback are an important and performance technique in D. The D2 full closure "feature" effectively removes it and makes D2 less attractive IMHO.

Not to mention that, among the top problems plaguing D2 currently, it should be one of the easier things to fix.  Far easier than figuring out overhauls for operator overloading, or construction syntax, or how ranges should work, or forward reference, or figuring out how 'shared' should work, or merging Tango and Phobos.   Compared to those it's pretty easy to solve this one!

Personally I think no alloc should be the default, with different syntax to get a full closure.  Using the "new" keyword somehow makes sense to me.

--bb
October 24, 2008
Frank Benoit wrote:
> Jason House schrieb:
>> I ported some monte carlo simulation code from Java to D2, and
>> performance is horrible.
>>
>> 34% of the execution time is used by std.random.uniform. To my great
>> surprise, 25% of the execution  time is memory allocation (and
>> collection) from that random call. The only candidate source I see is
>> a call to ensure with lazy arguments. The memory allocation occurs at
>> the start of the UniformDistribution call. I assume this is dynamic
>> closure kicking in.
>>
>> Can anyone verify that this is the case?
>>
>> 600000 memory allocations per second really kills performance!
> 
> It was written in this NG over and over. The D2 full closure feature is
> a BIG!!!! problem.
> 
> The nested functions passed as callback are an important and performance
> technique in D. The D2 full closure "feature" effectively removes it and
> makes D2 less attractive IMHO.

Agreed. Is it in bugzilla?
October 25, 2008
Jason House wrote:
> I ported some monte carlo simulation code from Java to D2, and
> performance is horrible.
> 
> 34% of the execution time is used by std.random.uniform. To my great
> surprise, 25% of the execution  time is memory allocation (and
> collection) from that random call. The only candidate source I see is
> a call to ensure with lazy arguments. The memory allocation occurs at
> the start of the UniformDistribution call. I assume this is dynamic
> closure kicking in.
> 
> Can anyone verify that this is the case?
> 
> 600000 memory allocations per second really kills performance!

std.random does not use dynamic memory allocation. Walter is almost done implementing static closures.

Andrei
October 25, 2008
bearophile wrote:

> Jason House:
> 
>> 34% of the execution time is used by std.random.uniform.
> 
> Kiss of Tango is much faster, and there's a much faster still (but good still) rnd generator around...
> 
> 
>> Can anyone verify that this is the case?
> 
> Can you show us a working minimal code I/we can test?
> 
> -------------------
> 
> Frank Benoit:
> 
>>The D2 full closure "feature" effectively removes it and makes D2 less attractive IMHO.<
> 
> The first simple solution is to add the possibility of adding "scope" to closures to not use the heap (but I don't know how to do that in every situation, and it makes the already long syntax of lambdas even longer).
> 
> But the probably best way for D to become more functional (and normal functional programming is often full of functions that move everywhere, often they are closures, but only virtually) is to grow some more optimizing capabilities, so closures aren't a problem anymore. There are many ways to perform such optimizations (but in a language mostly based on side effects it's less easy).
> 
> Bye,
> bearophile

The following spends 90% of its time in _d_alloc_memory
void bar(lazy int i){}
void foo(int i){ bar(i); }
void main(){ foreach(int i; 1..1000000) foo(i); }

Compiling with -O -release reduces it to 88% :)
October 25, 2008
On Sat, Oct 25, 2008 at 9:59 AM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> Jason House wrote:
>>
>> I ported some monte carlo simulation code from Java to D2, and performance is horrible.
>>
>> 34% of the execution time is used by std.random.uniform. To my great surprise, 25% of the execution  time is memory allocation (and collection) from that random call. The only candidate source I see is a call to ensure with lazy arguments. The memory allocation occurs at the start of the UniformDistribution call. I assume this is dynamic closure kicking in.
>>
>> Can anyone verify that this is the case?
>>
>> 600000 memory allocations per second really kills performance!
>
> std.random does not use dynamic memory allocation.

Well the suggestion is that it may be using dynamic memory allocation without intending to because of the dynamic closures.  Are you saying that is definitely not the case?

> Walter is almost done implementing static closures.

Excellent!  So what strategy is being used?  I hope it's static by default, dynamic on request, but your wording suggests otherwise.

--bb
« First   ‹ Prev
1 2 3