0

Boostを使用して行列代数を実行しています。この最適化が何かをするかどうかを理解しようとしています。オリジナル:

matrix<double> DoSomething(matrix<double> a, matrix<double> b)
{
    return a + b; //for example
}

最適化:

matrix<double>* DoSomething(matrix<double>* a, matrix<double>* b)
{
    return *a + *b; //for example
}

基本的に、パラメーターと戻り型としてポインターを使用すると、大きなオブジェクトをコピーできないと思いました。ソースコードを読んだ後、Boostublasが基本的にこれを処理するのだろうかと思います。Boostのコードで常に参照を扱っているようです。

4

2 に答える 2

3

それは最適化ではありません。実際、それは災害です。「最適化された」コードは、関数が戻ったときに存在しなくなった一時オブジェクトへのポインターを返します。これを修正しようとすると:

matrix<double>* DoSomething(matrix<double>* a, matrix<double>* b)
{
    return new Matrix<double>(*a + *b); //for example
}

さて、あなたがちょうどそこでしたことを見てください。a新しいマトリックスは、合計との結果である一時的なものからコピー構築されているため、コピーを作成するように要求しましたb。さらに悪いことに、このコードはもはや例外安全ではなく、呼び出し元を台無しにして、割り当てられたマトリックスを解放しないのは簡単です。

だからそれを放っておいてください。すでに最適化されており、簡単に壊したり悪化させたりすることができます。

于 2012-10-13T22:57:20.477 に答える
0

最高のパフォーマンスが必要な場合は、参照(またはポインター)を渡し、std :: move:で戻ります。

matrix<double>&& DoSomething(matrix<double>& a, matrix<double>& b)
{
    return std::move(a + b); 
}

したがって、引数と戻り値をコピーすることは避けますが、std ::moveはC++11でのみ使用できます。それ以外の場合は、行列を返します。

matrix<double> DoSomething(matrix<double>& a, matrix<double>& b)
{
    return a+b; 
}
于 2012-10-13T23:10:13.240 に答える