| Thread overview | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 24, 2008 Dynamic Closure + Lazy Arguments = Performance Killer? | ||||
|---|---|---|---|---|
| ||||
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 Re: Dynamic Closure + Lazy Arguments = Performance Killer? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jason House | 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 Re: Dynamic Closure + Lazy Arguments = Performance Killer? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Gregor Richards | 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 Re: Dynamic Closure + Lazy Arguments = Performance Killer? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jason House | 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 Re: Dynamic Closure + Lazy Arguments = Performance Killer? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jason House | 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 Re: Dynamic Closure + Lazy Arguments = Performance Killer? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit | 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 Re: Dynamic Closure + Lazy Arguments = Performance Killer? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit | 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 Re: Dynamic Closure + Lazy Arguments = Performance Killer? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jason House | 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 Re: Dynamic Closure + Lazy Arguments = Performance Killer? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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 Re: Dynamic Closure + Lazy Arguments = Performance Killer? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 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 | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply