Reputation: 55
So, I have a C++ Matrix class, and there are some overloaded operators(like +, *, %, - atc...), they look like this:
Matrix operator*(const Matrix& b) const;
They are returning the TMP object of type Matrix, and then it's being copied, whinch decreaces the performance.
If I do something like
Matrix some = a*b + c*d - (i+j)*m*b; //[1]
There are something about 6 copy constructors being called.
So, I saw ppl doing some template metaprogramming, to expand the [1] to something like:
Matrix some = ((a*b)+=(c*d))-=(((i+j)*=m)*=b); //[2]
The code at [2] gonna call somewhere around 3 copy constructors.(*=, += writing the results to left operand and returns the link for it)
Can you guys pls explain me, how do I do that via templates, or what should I read to understand how to do that.
Upvotes: 0
Views: 58
Reputation:
They keyword to search on is "expression templates".
A lot of things can be achieved simply by using rvalue references, though.
Incidentally, if you're really serious about it you'll want even more rewriting than your example suggests; e.g. multiply and addition steps often want to be combined into a single operation rather than two separate ones.
Upvotes: 1
Reputation: 55
So, as I saw in comments, compiller optimize it by itself, but, there are also some moments exists, that can be optimized.
Lets start.
.
...freeing memory, if needed...
if(!(tmp && !copied)
{
...memcpy actions...
}else
{
...assigning a pointers to allocated data right to our objects pointers...
this->arr = a.arr;
a.copied = true;
}
...other post actions...
also we need to change a deconctructor
~SomeClass()
{
if( !(tmp && copied) )//If its not a tmp and not copied then freeing
{
...freeing a memory...
}//otherwise just skeep
}
.
SomeClass operator+(SomeClass a)
{
...some code...
if(!(tmp || a.tmp))//if there is no tmp object, doing the same, as usual.
{
SomeClass res;
...some usual code
res.tmp = true;
res.copied = false;
return res;
}else
{
if(tmp)
{
...doing operations and storing them in this...
return *this;
}else //"a" is tmp
{
...doing operations and storing them in "a"...
return a;
}
}
}
so... by those actions we are decreasing the amounght of operations being called, we are saving a memory that would be allocated otherwise, also we are not copying memory from the operator results.
Now, code like this:
res = a * n + b * t - k;
will allocate memory only for a "a * n" and "b * t", then everything gonna be stored inside tmp objects of those operators results. And finally, we are not coping memory(values) from the tmp object to the "res", we are just simply assigning the pointers to a "tmp" memory(whinch is not gonna be freed).
Upvotes: 0