Thread overview | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 25, 2015 D needs emplacement new | ||||
---|---|---|---|---|
| ||||
Consider both of these scripts: test_gc_new.d (http://dpaste.dzfl.pl/4f36b165c502) and test_gc_emplace_new.d (http://dpaste.dzfl.pl/ff4e3c35479f) and these results: test_gc_new: >test_gc_new.exe "--DRT-gcopt=profile:1" Number of collections: 140 Total GC prep time: 0 milliseconds Total mark time: 5 milliseconds Total sweep time: 9 milliseconds Total page recovery time: 2 milliseconds Max Pause Time: 0 milliseconds Grand total GC time: 18 milliseconds GC summary: 5 MB, 140 GC 18 ms, Pauses 6 ms < 0 ms test_gc_emplace_new: >test_gc_emplace_new.exe "--DRT-gcopt=profile:1" Number of collections: 2 Total GC prep time: 0 milliseconds Total mark time: 0 milliseconds Total sweep time: 0 milliseconds Total page recovery time: 0 milliseconds Max Pause Time: 0 milliseconds Grand total GC time: 0 milliseconds GC summary: 5 MB, 2 GC 0 ms, Pauses 0 ms < 0 ms As you can see, thanks to the emplacement, I have 138 less GC collections. In C++ you can do new (f) Foo(...) instead of my New!(Foo)(f, ...) The C++ version is a lot more readable, nicer and safer. Therefore D should (since it says it is a system language like C++) add an equal syntax or, at least, implement a library version like mine to allow people a nice and easy way to reuse their object. We already have emplace (which my implementation uses) but to write emplace((cast(void*) obj)[0 .. __traits(classInstanceSize, Foo)], ...) is not nice, not intuitive and not safe and can be improved. |
April 25, 2015 Re: D needs emplacement new | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | You could just call the constructor again to reuse an object. I guess you should also reinitialize the memory, but that's pretty easy too. Instead of placement new to reuse an object, make a function like reset() or reinitialize() that destructs the first, then copies the init back over and calls the constructor again. Something like this: void reinitialize(ClassName, CtorArgs...)(ClassName obj, CtorArgs args) { assert(typeid(obj) == typeid(ClassName), "Don't use this on interfaces or base classes!"); static if(__traits(hasMember, obj, "__dtor")) obj.__dtor(); (cast(void*) obj)[0 .. typeid(obj).init.length] = typeid(obj).init[]; static if(__traits(hasMember, obj, "__ctor")) obj.__ctor(args); } Then, you create it however up front and just reinitialize it when you're all set. I think that is a bit clearer in meaning than placement new as well. |
April 25, 2015 Re: D needs emplacement new | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Saturday, 25 April 2015 at 18:46:52 UTC, Adam D. Ruppe wrote:
> You could just call the constructor again to reuse an object. I guess you should also reinitialize the memory, but that's pretty easy too.
>
> Instead of placement new to reuse an object, make a function like reset() or reinitialize() that destructs the first, then copies the init back over and calls the constructor again.
>
>
>
> Something like this:
>
> void reinitialize(ClassName, CtorArgs...)(ClassName obj, CtorArgs args) {
> assert(typeid(obj) == typeid(ClassName),
> "Don't use this on interfaces or base classes!");
> static if(__traits(hasMember, obj, "__dtor"))
> obj.__dtor();
> (cast(void*) obj)[0 .. typeid(obj).init.length] = typeid(obj).init[];
> static if(__traits(hasMember, obj, "__ctor"))
> obj.__ctor(args);
> }
>
>
> Then, you create it however up front and just reinitialize it when you're all set. I think that is a bit clearer in meaning than placement new as well.
Nice name, fits better. But that should be in phobos, don't you think?
|
April 25, 2015 Re: D needs emplacement new | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Saturday, 25 April 2015 at 18:50:59 UTC, Namespace wrote:
> Nice name, fits better. But that should be in phobos, don't you think?
meh, it might be nice to have, but not being in phobos isn't a big deal to me for little utilities like this.
|
April 25, 2015 Re: D needs emplacement new | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Saturday, 25 April 2015 at 18:46:52 UTC, Adam D. Ruppe wrote:
> You could just call the constructor again to reuse an object. I guess you should also reinitialize the memory, but that's pretty easy too.
>
> Instead of placement new to reuse an object, make a function like reset() or reinitialize() that destructs the first, then copies the init back over and calls the constructor again.
>
>
>
> Something like this:
>
> void reinitialize(ClassName, CtorArgs...)(ClassName obj, CtorArgs args) {
> assert(typeid(obj) == typeid(ClassName),
> "Don't use this on interfaces or base classes!");
> static if(__traits(hasMember, obj, "__dtor"))
> obj.__dtor();
> (cast(void*) obj)[0 .. typeid(obj).init.length] = typeid(obj).init[];
> static if(__traits(hasMember, obj, "__ctor"))
> obj.__ctor(args);
> }
>
>
> Then, you create it however up front and just reinitialize it when you're all set. I think that is a bit clearer in meaning than placement new as well.
doesn't this have the issue of not calling the ctor/dtor of nested objects?
|
April 25, 2015 Re: D needs emplacement new | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Saturday, 25 April 2015 at 18:57:13 UTC, Adam D. Ruppe wrote:
> On Saturday, 25 April 2015 at 18:50:59 UTC, Namespace wrote:
>> Nice name, fits better. But that should be in phobos, don't you think?
>
> meh, it might be nice to have, but not being in phobos isn't a big deal to me for little utilities like this
I'm sure newcomers (especially those coming from C++) would be delighted if they had the possibility to reuse their memory. In addition, it could be impossible for them to write such "hack" itself.
I already hear the cries: "D wasted memory" and: "I can not reuse my memory".
And then it would be less attractive for such people, to switch to D.
I would suggest something like:
----
T emplace(T, U...)(ref T obj, auto ref U args) if (is(T == class)) {
if (!obj)
return null;
import std.conv : emplace; // temporary, as long it is not in std.conv
enum ClassSizeOf = __traits(classInstanceSize, T);
void[] buf = (cast(void*) obj)[0 .. ClassSizeOf];
return emplace!(T)(buf, args);
}
T emplaceOrNew(T, U...)(ref T obj, auto ref U args) if (is(T == class)) {
if (!obj)
return new T(args);
return emplace(obj, args);
}
----
|
April 25, 2015 Re: D needs emplacement new | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Saturday, 25 April 2015 at 19:09:15 UTC, Namespace wrote: > On Saturday, 25 April 2015 at 18:57:13 UTC, Adam D. Ruppe wrote: >> On Saturday, 25 April 2015 at 18:50:59 UTC, Namespace wrote: >>> Nice name, fits better. But that should be in phobos, don't you think? >> >> meh, it might be nice to have, but not being in phobos isn't a big deal to me for little utilities like this > I'm sure newcomers (especially those coming from C++) would be delighted if they had the possibility to reuse their memory. In addition, it could be impossible for them to write such "hack" itself. > I already hear the cries: "D wasted memory" and: "I can not reuse my memory". > And then it would be less attractive for such people, to switch to D. > > I would suggest something like: > ---- > T emplace(T, U...)(ref T obj, auto ref U args) if (is(T == class)) { > if (!obj) > return null; > > import std.conv : emplace; // temporary, as long it is not in std.conv > > enum ClassSizeOf = __traits(classInstanceSize, T); > > void[] buf = (cast(void*) obj)[0 .. ClassSizeOf]; > return emplace!(T)(buf, args); > } > > T emplaceOrNew(T, U...)(ref T obj, auto ref U args) if (is(T == class)) { > if (!obj) > return new T(args); > return emplace(obj, args); > } > ---- hmm... http://dlang.org/phobos/std_conv.html#.emplace |
April 25, 2015 Re: D needs emplacement new | ||||
---|---|---|---|---|
| ||||
Posted in reply to weaselcat | On Saturday, 25 April 2015 at 19:14:41 UTC, weaselcat wrote:
> On Saturday, 25 April 2015 at 19:09:15 UTC, Namespace wrote:
>> On Saturday, 25 April 2015 at 18:57:13 UTC, Adam D. Ruppe wrote:
>>> On Saturday, 25 April 2015 at 18:50:59 UTC, Namespace wrote:
>>>> Nice name, fits better. But that should be in phobos, don't you think?
>>>
>>> meh, it might be nice to have, but not being in phobos isn't a big deal to me for little utilities like this
>> I'm sure newcomers (especially those coming from C++) would be delighted if they had the possibility to reuse their memory. In addition, it could be impossible for them to write such "hack" itself.
>> I already hear the cries: "D wasted memory" and: "I can not reuse my memory".
>> And then it would be less attractive for such people, to switch to D.
>>
>> I would suggest something like:
>> ----
>> T emplace(T, U...)(ref T obj, auto ref U args) if (is(T == class)) {
>> if (!obj)
>> return null;
>>
>> import std.conv : emplace; // temporary, as long it is not in std.conv
>>
>> enum ClassSizeOf = __traits(classInstanceSize, T);
>>
>> void[] buf = (cast(void*) obj)[0 .. ClassSizeOf];
>> return emplace!(T)(buf, args);
>> }
>>
>> T emplaceOrNew(T, U...)(ref T obj, auto ref U args) if (is(T == class)) {
>> if (!obj)
>> return new T(args);
>> return emplace(obj, args);
>> }
>> ----
>
> hmm...
> http://dlang.org/phobos/std_conv.html#.emplace
woops, accidentally posted before finishing
I was going to say that this should probably just be an overload of emplace if it isn't already, seems odd if it isn't.
|
April 25, 2015 Re: D needs emplacement new | ||||
---|---|---|---|---|
| ||||
Posted in reply to weaselcat | > hmm... > http://dlang.org/phobos/std_conv.html#.emplace > constructs an object of non-class type T at that address. Non-Class. ;) |
April 25, 2015 Re: D needs emplacement new | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Saturday, 25 April 2015 at 19:16:21 UTC, Namespace wrote:
>> hmm...
>> http://dlang.org/phobos/std_conv.html#.emplace
>
>> constructs an object of non-class type T at that address.
>
> Non-Class. ;)
There's a class overload 3 down
T emplace(T, Args...)(void[] chunk, auto ref Args args) if (is(T == class));
|
Copyright © 1999-2021 by the D Language Foundation