On Sun, 08 Feb 2009 10:26:37 +0300, Weed <resume...@mail.ru> wrote:

(Has started here:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=81359)

To me still does not give rest performance of classes (in comparison
with C++ or with D structs)

I still think that it is a serious problem.

Colleagues from our national D forum have asked to show it and I have
written simple examples on D. I want to share with you too them.

On my computer the code with structure (i.e. object by value) runs in 6
times faster than a code with a class:

$ time ./struct

real    0m8.515s
user    0m7.796s
sys     0m0.016s
$ time ./class

real    0m52.185s
user    0m40.543s
sys     0m0.076s

The code on C++ is also approximately in 6 times faster a code with
classes on D. (I do not give an example on C++ because classes on C++
work just as structures in D.)

I think with it it is necessary to do something.


Examples code:

//========================
struct C {
    int i;
    real[5] unused; // to prevent returning this object in registers

    C opAdd( C src ) {
        C ret;
        ret.i = i + src.i;
        return ret;
    }
}

int main() {
    C c1;
    C c2;

    // initialise i by "random" value to prevent compile-time calculation
    c1.i = cast(int)&c1;
    c2.i = 0;

    for(int i = 0; i < 50_000_000; ++i)
        c2 = c1 + c1 + c1;

    return c2.i;
}

//========================

class C {
    int i;
    real[5] unused; // to prevent returning this object in registers

    C opAdd( C src ) {
        auto ret = new C;
        ret.i = i + src.i;
        return ret;
    }
}

int main() {
    auto c1 = new C;
    auto c2 = new C;

    // initialise i by "random" value to prevent compile-time calculation
    c1.i = cast(int)&c1;
    c2.i = 0;

    for(int i = 0; i < 50_000_000; ++i)
        c2 = c1 + c1 + c1;

    return c2.i;
}
//========================

Your C objects have value semantics. For value semantics you should use value 
types.

Alternatively you may want to use the following trick (I used it for lazy 
string concatenation in C+):

class C
{
   int value;

   this(int dim)(ref Sum!(dim) sum)
   {
       value = sum.value;
   }

   Sum!(2) opAdd(C other)
   {
       return Sum!(2)(this, other);
   }
}

struct Sum(int dimension)
{
   private C[dimension] objects;

   this(C first, C second)
   {
       objects[0] = first;
       objects[1] = second;
   }

   this(int dim)(ref Sum!(dim) sum1, ref Sum!(dimension-dim) sum2)
   {
       objects[0..dim][] = sum1.objects[];
       objects[dim+1..dimension] = sum2.objects[];
   }

   this(ref Sum!(dimension-1) sum, C obj)
   {
       objects[0..$-1][] = sum.objects[];
       objects[$-1] = obj;
   }

   Sum!(dimension+1) opAdd(C other)
   {
       return Sum!(dimension+1)(this, other);
   }

   Sum!(dimension+otherDimension) opAdd(otherDimension)(Sum!(otherDimension) 
other)
   {
       return Sum!(dimension+otherDimension)(this, other);
   }

   int value() {
       int value = 0;
       foreach (C c; objects) {
           value += c.value;
       }
       return value;
   }
}

Apparently, it doesn't work at the moment because ctor can't be a template :(
Is there an enhancement request in bugzilla? It prevents this pattern from 
working.

Reply via email to