На практике реализации C ++ обычно реализуют передачу по ссылке, передавая указатель изнутри (при условии, что вызов не встроен).
Так что нет хитрого механизма, который позволял бы передавать по ссылке быстрее, так как передать указатель не быстрее, чем передать небольшое значение. Кроме того, передача по значению также может принести пользу от лучшей оптимизации, как только вы окажетесь в функции. Например:
int foo(const int &a, int *b) {
int c = a;
*b = 2;
return c + a;
}
Насколько известно компилятору, b
указывает на a
, что называется "псевдонимом". Если бы a
было передано по значению, эта функция могла бы оптимизироваться до эквивалента *b = 2; return 2*a;
. В современном конвейере инструкций ЦП это может быть больше похоже на «начало загрузки, начало сохранения b, ожидание загрузки a, умножение на 2, ожидание сохранения b, возврат», вместо «начать загрузку, начать сохранение b». , дождитесь загрузки a, дождитесь сохранения b, начните загрузку, дождитесь загрузки a, добавьте a к c, верните ", и вы начинаете понимать, почему потенциал для алиасов может оказать существенное влияние на производительность. В некоторых случаях, если не обязательно, огромный эффект в этом.
Конечно, алиасинг препятствует оптимизации только в тех случаях, когда он изменяет эффект функции для некоторого возможного ввода. Но только потому, что ваше намерение для функции состоит в том, что псевдонимы не должны когда-либо влиять на результаты, это не обязательно означает, что компилятор может предположить, что это не так: иногда в вашей программе псевдонимы не возникают, но компилятор не не знаю этого. И не обязательно должен быть второй параметр указателя, каждый раз, когда ваша функция вызывает код, который оптимизатор «не видит», он должен предполагать, что любая ссылка может измениться.