emplace, scope, enforce [Was: Re: Manual...]
Rory Mcguire
rjmcguire at gm_no_ail.com
Wed Jul 21 12:31:37 PDT 2010
Andrei Alexandrescu wrote:
> On 07/21/2010 01:59 PM, Rory Mcguire wrote:
>> Dmitry Olshansky wrote:
>>
>>> now replace the orignal while loop with this:
>>> while (i< N) {
>>> auto testObject = Scoped!Test(i, i, i, i, i, i);
>>> //assuming we have aforementioned evil function func(Test t),
>>> that keeps global reference to t.
>>> //fun(testObject); //uncoment to get an compile error - type
>>> mismatch
>>> testObject.doSomething(i, i, i, i, i, i);
>>> testObject.doSomething(i, i, i, i, i, i);
>>> testObject.doSomething(i, i, i, i, i, i);
>>> testObject.doSomething(i, i, i, i, i, i);
>>> i++;
>>> }
>>
>> With your code I `time` reports the below timings on my machine:
>> real 0m19.658s
>> user 0m19.590s
>> sys 0m0.010s
>>
>> compared to:
>> real 0m9.122s
>> user 0m9.090s
>> sys 0m0.000s
>>
>> with bearofiles original version. With -O -release its about 4 seconds
>> faster for each.
>
> I compiled and ran the tests myself with -O -release -inline and got
> 1.95s for Dmitry's implementation and 1.55s for bearophile's.
>
> I optimized Dmitry's implementation in two ways: I replaced the call to
> clear() with a straight call to the destructor and added = void in two
> places to avoid double initialization. I got 1.11s, which significantly
> undercuts the implementation using scope.
>
> Here's the code I used for testing:
>
> struct Scoped(T) {
> ubyte[__traits(classInstanceSize, Test)] _payload = void;
> T getPayload(){
> return cast(T)(_payload.ptr);
> }
> alias getPayload this;
>
> static Scoped opCall(Args...)(Args args)
> if (is(typeof(T.init.__ctor(args)))) {
> // TODO: should also provide decent error message
> Scoped!T s = void;
> emplace!T(cast(void[])s._payload,args);
> return s;
> }
> ~this() {
> static if (is(typeof(getPayload.__dtor()))) {
> getPayload.__dtor();
> }
> }
> }
>
> final class Test { // 32 bytes each instance
> int i1, i2, i3, i4, i5, i6;
> this(int ii1, int ii2, int ii3, int ii4, int ii5, int ii6) {
> this.i1 = ii1;
> this.i2 = ii2;
> this.i3 = ii3;
> this.i4 = ii4;
> this.i5 = ii5;
> this.i6 = ii6;
> }
> void doSomething(int ii1, int ii2, int ii3, int ii4, int ii5, int
> ii6) {
> }
> }
>
> void main(string[] args)
> {
> enum int N = 10_000_000;
> int i;
> while (i < N) {
> auto testObject = Scoped!Test(i, i, i, i, i, i);
> //scope testObject = new Test(i, i, i, i, i, i);
> testObject.doSomething(i, i, i, i, i, i);
> testObject.doSomething(i, i, i, i, i, i);
> testObject.doSomething(i, i, i, i, i, i);
> testObject.doSomething(i, i, i, i, i, i);
> i++;
> }
> }
>
>
> Andrei
Thanks Andrei!!!
More information about the Digitalmars-d
mailing list