Thread overview | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 08, 2009 Old problem with performance | ||||
---|---|---|---|---|
| ||||
(Has started here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=81359) To me still does not give rest performance of classes (in comparison with C++ or with D structs) I still think that it is a serious problem. Colleagues from our national D forum have asked to show it and I have written simple examples on D. I want to share with you too them. On my computer the code with structure (i.e. object by value) runs in 6 times faster than a code with a class: $ time ./struct real 0m8.515s user 0m7.796s sys 0m0.016s $ time ./class real 0m52.185s user 0m40.543s sys 0m0.076s The code on C++ is also approximately in 6 times faster a code with classes on D. (I do not give an example on C++ because classes on C++ work just as structures in D.) I think with it it is necessary to do something. Examples code: //======================== struct C { int i; real[5] unused; // to prevent returning this object in registers C opAdd( C src ) { C ret; ret.i = i + src.i; return ret; } } int main() { C c1; C c2; // initialise i by "random" value to prevent compile-time calculation c1.i = cast(int)&c1; c2.i = 0; for(int i = 0; i < 50_000_000; ++i) c2 = c1 + c1 + c1; return c2.i; } //======================== class C { int i; real[5] unused; // to prevent returning this object in registers C opAdd( C src ) { auto ret = new C; ret.i = i + src.i; return ret; } } int main() { auto c1 = new C; auto c2 = new C; // initialise i by "random" value to prevent compile-time calculation c1.i = cast(int)&c1; c2.i = 0; for(int i = 0; i < 50_000_000; ++i) c2 = c1 + c1 + c1; return c2.i; } //======================== |
February 08, 2009 Re: Old problem with performance | ||||
---|---|---|---|---|
| ||||
Posted in reply to Weed |
Weed wrote:
> [snip]
If I had to take a guess, I'd say that it's six times slower because you're performing 100 million allocations. You aren't benchmarking class/struct overhead, you're benchmarking the overhead of doing 100 million allocations.
You're comparing apples and heffalumps.
-- Daniel
|
February 08, 2009 Re: Old problem with performance | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | Daniel Keep пишет:
> Weed wrote:
>> [snip]
>
> If I had to take a guess, I'd say that it's six times slower because you're performing 100 million allocations. You aren't benchmarking class/struct overhead, you're benchmarking the overhead of doing 100 million allocations.
>
> You're comparing apples and heffalumps.
Yes, but problem is that D does not leave way to create a class instance without allocation
|
February 08, 2009 Re: Old problem with performance | ||||
---|---|---|---|---|
| ||||
Posted in reply to Weed | Weed пишет:
> Daniel Keep пишет:
>> Weed wrote:
>>> [snip]
>> If I had to take a guess, I'd say that it's six times slower because you're performing 100 million allocations. You aren't benchmarking class/struct overhead, you're benchmarking the overhead of doing 100 million allocations.
>>
>> You're comparing apples and heffalumps.
>
> Yes, but problem is that D does not leave way to create a class instance without allocation
I should explain that I compare not only structs and classes in D but also classes in C++, there classes work as fast as well as structures in case of usage of overload of operators.
|
February 08, 2009 Re: Old problem with performance | ||||
---|---|---|---|---|
| ||||
Posted in reply to Weed | Weed wrote:
> Daniel Keep пишет:
>> Weed wrote:
>>> [snip]
>> If I had to take a guess, I'd say that it's six times slower because
>> you're performing 100 million allocations. You aren't benchmarking
>> class/struct overhead, you're benchmarking the overhead of doing 100
>> million allocations.
>>
>> You're comparing apples and heffalumps.
>
> Yes, but problem is that D does not leave way to create a class
> instance without allocation
You can allocate a class on the stack with:
scope c = new C();
|
February 08, 2009 Re: Old problem with performance | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote:
> Weed wrote:
>> Daniel Keep пишет:
>>> Weed wrote:
>>>> [snip]
>>> If I had to take a guess, I'd say that it's six times slower because
>>> you're performing 100 million allocations. You aren't benchmarking
>>> class/struct overhead, you're benchmarking the overhead of doing 100
>>> million allocations.
>>>
>>> You're comparing apples and heffalumps.
>>
>> Yes, but problem is that D does not leave way to create a class
>> instance without allocation
>
> You can allocate a class on the stack with:
>
> scope c = new C();
Which helps (a bit) with the two instances allocated in main(), but is rather unhelpful with the 100_000_000 allocated in opAdd() (they're returned)...
|
February 08, 2009 Re: Old problem with performance | ||||
---|---|---|---|---|
| ||||
Posted in reply to Weed | On Sun, 08 Feb 2009 10:26:37 +0300, Weed <resume755@mail.ru> wrote: > (Has started here: > http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=81359) > > To me still does not give rest performance of classes (in comparison > with C++ or with D structs) > > I still think that it is a serious problem. > > Colleagues from our national D forum have asked to show it and I have > written simple examples on D. I want to share with you too them. > > On my computer the code with structure (i.e. object by value) runs in 6 > times faster than a code with a class: > > $ time ./struct > > real 0m8.515s > user 0m7.796s > sys 0m0.016s > $ time ./class > > real 0m52.185s > user 0m40.543s > sys 0m0.076s > > The code on C++ is also approximately in 6 times faster a code with > classes on D. (I do not give an example on C++ because classes on C++ > work just as structures in D.) > > I think with it it is necessary to do something. > > > Examples code: > > //======================== > struct C { > int i; > real[5] unused; // to prevent returning this object in registers > > C opAdd( C src ) { > C ret; > ret.i = i + src.i; > return ret; > } > } > > int main() { > C c1; > C c2; > > // initialise i by "random" value to prevent compile-time calculation > c1.i = cast(int)&c1; > c2.i = 0; > > for(int i = 0; i < 50_000_000; ++i) > c2 = c1 + c1 + c1; > > return c2.i; > } > > //======================== > > class C { > int i; > real[5] unused; // to prevent returning this object in registers > > C opAdd( C src ) { > auto ret = new C; > ret.i = i + src.i; > return ret; > } > } > > int main() { > auto c1 = new C; > auto c2 = new C; > > // initialise i by "random" value to prevent compile-time calculation > c1.i = cast(int)&c1; > c2.i = 0; > > for(int i = 0; i < 50_000_000; ++i) > c2 = c1 + c1 + c1; > > return c2.i; > } > //======================== Your C objects have value semantics. For value semantics you should use value types. Alternatively you may want to use the following trick (I used it for lazy string concatenation in C+): class C { int value; this(int dim)(ref Sum!(dim) sum) { value = sum.value; } Sum!(2) opAdd(C other) { return Sum!(2)(this, other); } } struct Sum(int dimension) { private C[dimension] objects; this(C first, C second) { objects[0] = first; objects[1] = second; } this(int dim)(ref Sum!(dim) sum1, ref Sum!(dimension-dim) sum2) { objects[0..dim][] = sum1.objects[]; objects[dim+1..dimension] = sum2.objects[]; } this(ref Sum!(dimension-1) sum, C obj) { objects[0..$-1][] = sum.objects[]; objects[$-1] = obj; } Sum!(dimension+1) opAdd(C other) { return Sum!(dimension+1)(this, other); } Sum!(dimension+otherDimension) opAdd(otherDimension)(Sum!(otherDimension) other) { return Sum!(dimension+otherDimension)(this, other); } int value() { int value = 0; foreach (C c; objects) { value += c.value; } return value; } } Apparently, it doesn't work at the moment because ctor can't be a template :( Is there an enhancement request in bugzilla? It prevents this pattern from working. |
February 08, 2009 Re: Old problem with performance | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denis Koroskin | Denis Koroskin пишет: > Your C objects have value semantics. For value semantics you should use value types. At present in D is not contain support of value types for objects. (I consider that it is necessary) > Alternatively you may want to use the following trick (I used it for lazy string concatenation in C+): [skip] > Apparently, it doesn't work at the moment because ctor can't be a > template :( > Is there an enhancement request in bugzilla? It prevents this pattern > from working. + it is difficult and also it will be even more difficult if it will be necessary to make support for the construction like: space_ship_1.calculatePathTo("Moon").getCheckpoint(3).getCoords; In this example we create a temporary class "path", create temporary class "checkpoint" and we take coords of checkpoint of this path. It is not expedient to us to store all this path and checkpoint because it is vary. (from http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=81432) |
February 08, 2009 Re: Old problem with performance | ||||
---|---|---|---|---|
| ||||
Posted in reply to Weed | On Sun, 08 Feb 2009 17:07:31 +0300, Weed <resume755@mail.ru> wrote:
> Denis Koroskin пишет:
>
>> Your C objects have value semantics. For value semantics you should use value types.
>
> At present in D is not contain support of value types for objects.
> (I consider that it is necessary)
>
>> Alternatively you may want to use the following trick (I used it for lazy string concatenation in C+):
>
> [skip]
>
>> Apparently, it doesn't work at the moment because ctor can't be a
>> template :(
>> Is there an enhancement request in bugzilla? It prevents this pattern
>> from working.
>
> + it is difficult and also it will be even more difficult if it will be
> necessary to make support for the construction like:
>
> space_ship_1.calculatePathTo("Moon").getCheckpoint(3).getCoords;
>
> In this example we create a temporary class "path", create temporary
> class "checkpoint" and we take coords of checkpoint of this path. It is
> not expedient to us to store all this path and checkpoint because it is
> vary.
>
> (from
> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=81432)
I believe you should stick with structs for that.
|
February 08, 2009 Re: Old problem with performance | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denis Koroskin | Denis Koroskin пишет:
>>
>> [skip]
>>
>>> Apparently, it doesn't work at the moment because ctor can't be a
>>> template :(
>>> Is there an enhancement request in bugzilla? It prevents this pattern
>>> from working.
>>
>> + it is difficult and also it will be even more difficult if it will be necessary to make support for the construction like:
>>
>> space_ship_1.calculatePathTo("Moon").getCheckpoint(3).getCoords;
>>
>> In this example we create a temporary class "path", create temporary class "checkpoint" and we take coords of checkpoint of this path. It is not expedient to us to store all this path and checkpoint because it is vary.
>>
>> (from
>> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=81432)
>>
>
> I believe you should stick with structs for that.
>
Let's assume, polymorphism is necessary to these objects
|
Copyright © 1999-2021 by the D Language Foundation