Я пытаюсь уменьшить объем памяти приложения, разработанного в основном на C ++, и одна из вещей, на которые я обращал внимание, — возвращать особенно большую структуру данных по ссылкам, а не возвращать их по значению. Мне нужно было подтверждение на это. Например, скажем, у меня есть функции-члены в классе some_object
следующее:
const some_type& get_some_type(...) {
...;
return ...;
}
против
const some_type get_some_type(...) {
...;
return ...;
}
Правильно ли я понимаю, что присвоение путем вызова последнего (возврат по значению) оставило бы две копии данных some_type
в памяти в определенных точках во время выполнения приложения, хотя вызов первого (возврат по ссылке) позволяет избежать этого?
Еще одно усилие в рамках общей цели сокращения объема памяти заключалось в изменении самого определения some_type
таким образом, чтобы исключить использование опции возврата по ссылке выше. В таком случае, так как some_type
(который на самом деле является своего рода контейнером, скажем, данных типа data_type
) используется внутри цикла следующим образом:
const some_type& = some_object->get_some_type(); // returns by ref. a large container
for(...) {
...;
data_type = some_type.at(...);
...;
}
Я предполагаю, что если мы будем вынуждены использовать приведенный выше возврат по значению, то мне нужно будет внести изменения следующим образом, введя новую функцию get_some_type_at
чтобы получить элемент контейнера по значению (есть ли недостатки в этом, о которых я должен знать, скажем, по производительности?):
for(...) {
...;
data_type = some_object->get_some_type_at(...); // returns by value a small object
...;
}
Опять же, я в основном ищу подтверждение этих аспектов. Но детали и идеи наиболее ценны. Спасибо за ваше время и интерес!
Большинство хороших компиляторов реализуют оптимизация возвращаемого значения, так что вам не нужно беспокоиться о ненужном построении объектов копирования.
Следовательно, выберите
some_type get_some_type(...) {
...;
return ...;
}
если вы не используете старый компилятор.
(Благодарность juanchopanza; также опустите возврат объекта const; объяснение в комментариях.)
Увидеть http://en.wikipedia.org/wiki/Return_value_optimization Больше подробностей; Бессмысленно дублировать это здесь.
Верно ли мое понимание того, что присвоение путем вызова последнего (возврат по значению) оставило бы две копии данных some_type в памяти в определенных точках во время выполнения приложения, в то время как вызывающий первый (возврат по ссылке) избегает этого?
С современным компилятором шансы на это довольно невелики. Стандарт специально благословляет то, что называется оптимизацией возвращаемого значения (и названной оптимизацией возвращаемого значения), чтобы позволить компилятору избежать создания дополнительных копий в подобном случае. Каждый достаточно современный компилятор, о котором я знаю, включает эту оптимизацию. В некоторых случаях (например, GCC) они делают эту оптимизацию четное когда вы говорите компилятору не сделать оптимизацию. С включенной оптимизацией вам нужно будет найти что-то около 10 лет (а может и больше), чтобы найти компилятор, который этого не делал.
В C ++ 11 добавлена возможность «переместить», чтобы сделать еще больше для решения проблемы, с которой вы столкнулись, даже когда вы возвращаете большой объект по значению.
Итог: мне кажется, что вы ищете не в том месте — вы можете рассмотреть возможность добавления явного конструктора перемещения (и, возможно, оператора перемещения) в ваш класс, но в целом вы можете просто вернуть по значению и будь счастлив.