Некоторые факторы, которые следует добавить к прекрасному совету Джереми:
1) Передача по значению работает эффективно только для небольших сообщений.Если в начале данных есть неиспользуемая область [cache-line-size], чтобы избежать ложного совместного использования, вы уже приближаетесь к размеру, когда передача по ссылке более эффективна.
2) Более широкие очереди означают, что требуется больше меставверх по очередям, что влияет на использование памяти.
3) Копирование данных в / из широких структур очереди требует времени.Помимо фактического использования ЦП при перемещении данных, очередь остается заблокированной во время копирования.Это увеличивает конкуренцию в очереди и приводит к общему снижению производительности, зависящему от ширины очереди.Если в вашем коде есть потенциал взаимоблокировки, сохранение блокировок в течение длительных периодов не поможет.
4) Передача по значению приводит к коду, который зависит от размера данных, т.е.исправлено во время компиляции.Помимо неприятного заражения шаблонами, это очень затрудняет настройку размеров буфера и т. Д. Во время выполнения.
5) Если сообщения передаются по ссылке и имеют неправильный / освобожденный / новый / удаленный / GC'd, это может привести к чрезмерному конфликту со стороны диспетчера памяти и частому расточительному сборщику мусора.Я обычно использую фиксированные пулы сообщений, выделяемые при запуске, специально, чтобы избежать этого.
6) Обработка байтовых потоков может быть неудобной при передаче по ссылке.Если поток байтов характеризуется частой доставкой отдельных байтов, передача по ссылке является разумной, только если байты разбиты на части.Это может привести к необходимости тайм-аутов, чтобы обеспечить своевременную отправку частично заполненных сообщений в следующий поток.Это приводит к усложнению и задержке.
7) Проекты с передачей по ссылке по своей природе более подвержены утечкам.Это может привести к увеличению времени тестирования и передозировке на valgrind - особенно болезненная зависимость (еще одна причина, по которой я использую пулы объектов сообщений фиксированного размера).
8) Сложные сообщения, например.те, которые содержат ссылки на другие объекты, могут вызвать ужасные проблемы с владением и управлением временем жизни, если передаются по значению.Пример - объект сокета сервера имеет ссылку на объект списка буферов, который содержит массив экземпляров буфера различного размера (реальный пример с сервера IOCP).Попробуйте передать это по значению ..
9) Многие вызовы ОС не могут обрабатывать ничего, кроме указателя.Вы не можете PostMessage (это Windows API, для всех вас, кто счастлив), даже 256-байтовую структуру по значению за один вызов (у вас есть только 2 целых числа wParam, lParam).Вызовы, которые устанавливают асинхронные обратные вызовы, часто позволяют отправлять «данные контекста» на обратный вызов - почти всегда только один указатель.Любое приложение, которое собирается использовать такую функциональность ОС, почти вынуждено прибегать к передаче по ссылке.