Ради аргумента давайте проигнорируем тривиальный случай, когда оптимизаторы удаляют различия. Предположим также, что вы используете 64-разрядные соглашения о вызовах Intel (которые отличаются от Linux ABI), и у вас есть 4 64-разрядных регистра для передачи таких значений, прежде чем прибегать к их помещению в стек. Это явно лучше.
Для 32-битных приложений, по значению, и они идут прямо в стек. Ссылка может вместо этого поместить указатель в регистр (опять же, несколько таких регистров разрешено перед использованием стека). Мы можем сделать это в некотором выводе из g ++ -O3 -S, вызывая f1 (99) по значению и f2 (101) по константной ссылке:
void f1(int64_t);
void f2(const int64_t&);
int main()
{
f1(99);
f2(101);
}
...
pushl 0
pushl $99
call _Z2f1x // by value - pushed two halves to stack
leal -8(%ebp), %eax
movl %eax, (%esp)
movl $101, -8(%ebp)
movl $0, -4(%ebp)
call _Z2f2RKx // by const& - ugly isn't it!?!
Затем вызываемая функция должна получить данные перед первым использованием (если есть). Вызываемая функция может свободно кэшировать значения, считанные в регистрах, так что это необходимо только один раз. При использовании стекового подхода значение может быть перечитано по желанию, поэтому регистр не нужно резервировать для этого значения. При подходе с указателем может потребоваться сохранить либо указатель, либо 64-битное значение где-то более предсказуемым (например, выдвинутый или другой менее полезный регистр), если этот регистр необходимо на мгновение освободить для какой-либо другой работы, но 64-битный Параметр int понадобится снова позже. В общем, трудно догадаться, что быстрее - может зависеть от процессора / использования регистра / оптимизатора / и т. Д., И не стоит пытаться.
Узел к совету PST ...
"эффективность" :( ПОЦЕЛУЙ. Передавай, как проходишь через каждое кровавое целое число. - pst
... хотя иногда вы применяете KISS к параметрам шаблона и делаете их все постоянными, даже если некоторые из них могут вписываться в регистры ....