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