Optimize my code =)

Stanislav Blinov stanislav.blinov at gmail.com
Sat Feb 15 15:31:20 PST 2014


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.


More information about the Digitalmars-d-learn mailing list