On Saturday, 15 February 2014 at 23:06:27 UTC, Robin wrote:

Matrix is still a class but I changed it to a final class preventing matrix methods to be virtual. Dimension is now a final struct (don't know if 'final' is affecting structs in any way tough ...).

It doesn't. It may even be disallowed someday, when it's fixed :)

This mainly gave the multiplication a huge performance boost.

When converting the Matrix to a struct from class the multiplication even lowered from ~4.3 seconds to about 3.6 seconds. However, I am currently not sure if I want matrices to be structs (value types).

Make them value types. If you're using dynamic arrays for storage, you're already using GC plenty, no need for additional allocations (and see below for copy and move semantics). Don't forget a postblit though.

(In the C++ matrix codes this scenario would actually call move assignment operator for matrix m3 which is much much faster than copying.)

D performs return value optimization: it moves result whenever it can.

But I haven't figured out yet how to use move semantics in D with class objects. Or is that just possible with struct value types?

Yup, it "just works". In most cases, anyway.
But move semantics in D differ from C++: D doesn't have rvalue references, and thus the compiler only performs a move when it can prove that value will no longer be used (there's a lengthy description in TDPL but I'm too lazy now to fetch it for exact citation :) ). For explicit moves, there's std.algorithm.move(), though AFAIK it's underimplemented at the moment.

I have also tried the LDC compiler. However, it gave me some strange bugs. E.g. it didn't like the following line:

ref Matrix transpose() const {
        return new Matrix(this).transposeAssign();
}

And it forced me to change it to:

ref Matrix transpose() const {
        auto m = new Matrix(this);
        m.transposeAssign();
        return m;
}

Which is kind of ugly ...
I hope that this is getting fixed soon, as I imply it as correct D code because the DMD is capable to compile this correctly.

Yes, this should be allowed. But you could also just write (new Matrix(this)).transposeAssign() :) Also, there's no point in ref return when you're returning a reference to class instance.

T opIndex(in size_t row, in size_t col) const nothrow
in {
    assert(row < nRows);
    assert(col < nCols);
} body {
    return data[dim.offset(row, col)];
}

The in and body statements are cool as far as I realize what they are for. ...so I think that the compiler won't optimize things in an 'in' code block - is that right?

in/out contracts are debug creatures anyway, they're not present in -release builds.

Reply via email to