Когда объект достаточно велик, что есть усиление производительности при передаче его по ссылке вместо значения?

Как ответил в этом вопросе Чарльз Бейли прохождение постоянной ссылкой, следует учитывать, когда тип объекта большой, но какой объект считается большим?

EDIT: ОК для предоставления большего количества данных, которые могут быть использованы для обеспечения более конкретного ответа, я решил добавить к этому описанию реальную проблему.

Предположим, что у нас есть такой объект:

typedef struct dipl { quint16 __id; quint16 __pos; quint16 __len; } data; 

И у нас есть еще один такой объект:

 class bidipl { public: bidipl(); quint8 id(); void setid(quint8 __id); void appenddipl(dipl __dipl); private: qint8 _M_id; dipllist _M_dipllist; }; 

Где dipllisttypedef QList dipllist; , Объекты dipl и bidipl создаются один раз, но доступны более чем через 100 раз в минуту. Итак, как мы должны передавать dipl в нашу функцию append?

 void appenddipl(dipl __dipl); 

Или же

 void appenddipl(const dipl& __dipl); 

Что следует считать достаточно большим, чтобы оправдать передачу по ссылке вместо ее значения? Вы найдете ответы, отличающиеся от:

  • все, что больше, чем естественный тип данных на процессоре (32 бит на x86, 64-бит на x86-64): здесь даже std::pair следует передавать по ссылке.

в

  • только контейнеры, которые хранят данные в динамической памяти (например, vectors , strings )

Мой личный вкус: примитивные данные по стоимости, структуры по ссылке.

Единственный продуктивный ответ, который вы найдете, профилируя конкретное приложение по конкретной архитектуре. Любые разговоры о производительности без фактического профилирования напрасны .

Существуют две отдельные затраты, связанные с передачей объектов по значению: копирование представления данных и выполнение конструкторов. Вы должны учитывать стоимость обоих.

  • Копирование данных, как правило, происходит быстро, но держите его в разумных пределах. Все в порядке передать struct { int[7]; } struct { int[7]; } по значению, но, вероятно, не столько для struct { int[20000]; } struct { int[20000]; } .

  • Выполняющие конструкторы могут выполнять динамическое распределение, что приводит к риску исключений и стоимости синхронизации. Это может быть незначительным, или это может быть важно. Это зависит.

Единственные переменные, которые вы, вероятно, должны передавать по значению безоговорочно, – это те, которые имеют размерность, встроенные типы. Во всем остальном вы должны думать о компромиссах.

Как сказал Чарльз, когда значение, о котором идет речь, имеет размер, равный или меньший, чем размер ссылки на объект, существует очевидное увеличение производительности для просто передачи значения вместо ссылки. Однако, поскольку доступ к значению МОЖЕТ требовать операции разыменования, в зависимости от деталей о контексте и того, как «умный» компилятор, он все равно может «стоить того», чтобы передать значение, размер которого немного больше, чем ссылка. Тем не менее, это начинает расщеплять волосы и редко бывает значительным.

Все, что не является фундаментальным типом, что означает любой объект classа, структуру или контейнер