Я использую 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
}
По сути, я предполагал, что использование указателей в качестве параметров и возвращаемого типа предотвратит копирование большого объекта. После прочтения исходного кода мне интересно, позаботится ли об этом Boost ublas. Кажется, вы всегда имеете дело со ссылкой в коде Boost.
Это не оптимизация. На самом деле это катастрофа. Ваш «оптимизированный» код возвращает указатель на временный объект, который больше не существует, когда функция возвращается. Если вы попытаетесь это исправить:
matrix<double>* DoSomething(matrix<double>* a, matrix<double>* b)
{
return new Matrix<double>(*a + *b); //for example
}
Ну, посмотри, что ты там только что сделал. Вы только что попросили создать копию, так как ваша новая матрица построена из копии из временного результата, который получается в результате суммирования a
а также b
, Хуже того, теперь этот код больше не является безопасным для исключений, и его легко обойти в вызывающей программе и не освобождать выделенную матрицу.
Так что оставь это в покое. Он уже оптимизирован, и вы можете легко сломать его или сделать хуже.
Если вам нужна лучшая производительность, передайте ссылки (или указатели) и вернитесь с помощью 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;
}