Есть ли преимущество в использовании указателей или ссылок для возврата буст-матриц?

Я использую 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.

2 ответа

Это не оптимизация. На самом деле это катастрофа. Ваш "оптимизированный" код возвращает указатель на временный объект, который больше не существует, когда функция возвращается. Если вы попытаетесь это исправить:

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; 
}
Другие вопросы по тегам