Вот фрагмент, получающий данные из буферизованного источника и отправляющий их для обработки. Если очередь пуста, get () возвращает ноль, а метод процесса с удовольствием принимает ноль и ничего не делает.
Какой самый оптимальный способ кодировать это?
something a; // any legal C++ return type...
aQueueOfSomethings g;
while (true) {
a=g.get();
process(a);
}
Невозможно предсказать значения, поступающие с помощью get (), они являются такими, какие они есть, и их необходимо снять с очереди и передать в process () как можно быстрее.
Я не вижу здесь много напрасных усилий - если я пропущу явную локальную переменную с именем 'a' и сделаю цикл одним слоем:
process(g.get());
неявное возвращаемое значение g.get () будет по-прежнему иметь выделенное пространство, может включать вызов конструктора и т. Д. И т. Д.
Если возвращаемая вещь имеет какой-либо размер или сложность, было бы лучше иметь указатель на нее, а не ее копию, и передавать этот указатель, а не копию по значению ... Поэтому я бы предпочел иметь
something *a;
g.get(a);
process(a);
вместо
something a;
a=g.get();
process(a);
Я написал тестовый пример на c ++, пробуя две строчные и однострочные версии, цикл 100 000 000 раз.
Если a - это объект с 4 целыми и 2 числами с плавающей запятой, и метод process () касается их всех, двухстрочное решение на самом деле быстрее! Если объект является единственным int, однострочная версия работает быстрее. Если объект сложный, но метод process () касается только одного значения, однострочная версия работает быстрее.
Наиболее интересным для меня является то, что при использовании компилятора g ++, Mac OS X 10.5.8, переключатель оптимизации первого уровня -O обеспечивает идентичную, намного более быструю работу как с 1, так и с 2-строчной версией.
Кроме того, что компилятор может оптимизировать, одну строку для обоих методов и не указывать явную промежуточную переменную и передавать по ссылке, чтобы избежать копирования, есть ли что-нибудь, что обычно заставляло бы его работать быстрее? Я чувствую, что упускаю что-то очевидное.