emplace, scope, enforce [Was: Re: Manual...]
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Wed Jul 21 12:16:15 PDT 2010
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
More information about the Digitalmars-d
mailing list