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!!!