Что является преимуществами для передачи целочисленных типов константой касательно

Требование реального мира я недавно добрался:

Требование A: Реализуйте эту опцию после полного понимания Требования A.

9
задан DeusAduro 13 November 2009 в 06:47
поделиться

12 ответов

Передача встроенного типа int с помощью const ref на самом деле будет незначительной деоптимизацией (обычно). По крайней мере, для не встроенной функции. Компилятору может потребоваться передать указатель, ссылку на который нужно разорвать, чтобы получить значение. Вы можете подумать, что это всегда можно оптимизировать, но правила псевдонима и необходимость поддержки отдельной компиляции могут заставить компилятор работать.

Однако для вашего второстепенного вопроса:

Для очень маленьких встроенных функций компилятор должен сделать копию целого числа в случае №2? Сообщив компилятору, что мы не будем изменять ссылку, может ли он встроить вызов функции без ненужного копирования целого числа?

Компилятор должен иметь возможность оптимизировать копию или разыменование, если семантика позволяет это; поскольку в этой ситуации компилятор полностью осведомлен о состоянии в месте вызова и реализации функции. Скорее всего, он просто загрузит значение в регистр и просто использует регистр для чего-то еще, когда это будет сделано с параметром. Конечно, все это очень зависит от фактической реализации функции.

12
ответ дан 4 December 2019 в 06:26
поделиться

Это зависит от компилятора, но я ожидаю, что любой разумный оптимизатор даст вам те же результаты в любом случае.

I протестирован с помощью gcc, и результаты действительно были такими же. вот код, который я тестировал:

inline int foo(const int& n) {
  return n * 2;
}

int bar(int x) {
  int y = foo(x);
  return y;
}

(с и без const & в параметре n foo)

Затем я скомпилировал с gcc 4.0.1 с помощью следующей командной строки:

g++ -O3 -S -o foo.s foo.cc

Результаты двух компиляций были идентичны.

7
ответ дан 4 December 2019 в 06:26
поделиться

Меня действительно раздражает, когда кто-то использует такие константные ссылки для основных типов данных. Я не вижу в этом никакой пользы, хотя можно утверждать, что для типов данных больше, чем sizeof (pointer) , это может быть более эффективным. Хотя, мне правда наплевать на такие мелкие «оптимизации».

6
ответ дан 4 December 2019 в 06:26
поделиться

Обычно это того не стоит. Даже для встроенной функции компилятор не будет глупым. Единственный раз, когда я бы сказал, это уместно, это если у вас есть шаблон;

4
ответ дан 4 December 2019 в 06:26
поделиться

Многие люди говоря, что между ними нет разницы. Я вижу один (возможно, надуманный) случай, в котором разница будет иметь значение ...

int i = 0;

void f(const int &j)
{
    i++;

    if (j == 0)
    {        
        // Do something.
    }
}

void g()
{
    f(i);
}

Но ... Как уже упоминали другие ... целые числа и указатели, вероятно, будут иметь одинаковый размер. Для чего-то такого маленького, как целое число, ссылки снизят вашу производительность. Наверное, победил Это будет тоже заметно, если ваш метод не вызывается часто, но он будет там. С другой стороны, при некоторых обстоятельствах компилятор может его оптимизировать.

2
ответ дан 4 December 2019 в 06:26
поделиться

При написании или использовании шаблонов вы можете получить (const int &), потому что автор шаблона не может знать, что это за тип на самом деле. Если объект тяжелый, то правильным решением будет передача ссылки; если это int или что-то в этом роде, компилятор может его оптимизировать.

В отсутствие каких-либо внешних требований, как правило, нет причин делать что-то подобное для одноразовой функции - это просто лишний набор текста и перебрасывание ссылок на самом деле препятствуют оптимизации. Копирование небольших данных в регистры намного дешевле, чем их перезагрузка из памяти в случае их изменения!

2
ответ дан 4 December 2019 в 06:26
поделиться

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

1
ответ дан 4 December 2019 в 06:26
поделиться

Вы можете использовать boost :: call_traits :: param_type для оптимальной передачи параметров. По умолчанию используется простая передача параметров примитивных типов и передача по константной ссылке структур и классов.

2
ответ дан 4 December 2019 в 06:26
поделиться

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

Просто копируйте по значению, придерживаясь неизменного соглашения для встроенных типов.

1
ответ дан 4 December 2019 в 06:26
поделиться

Дело не только в производительности. Правдивая история: на этой неделе я заметил, что коллега попытался улучшить числовые рецепты и заменил макрос


    #define SHFT(a,b,c,d) do { (a)=(b); (b)=(c); (c)=(d); } while (0)

этой функцией


    inline void Rotate(double& dFirst, double& dSecond, double& dThird, const double dNewValue)
    {
        dFirst = dSecond;
        dSecond = dThird;
        dThird = dNewValue;
    }   // Function Rotate

. Это сработало бы, если бы он передал последний параметр по ссылке, но так как он есть этот код

 
        Rotate(dum,*fb,*fa,dum);

, который должен был поменять местами * fa и * fb, больше не работает. Передача его по ссылке без const невозможна, так как в других местах последнему параметру передаются не-l-значения.

0
ответ дан 4 December 2019 в 06:26
поделиться

Не делайте этого. int имеет тот же размер, что и указатель / ссылка на обычных 32-битных платформах, и меньше на 64-битных, таким образом, вы можете получить снижение производительности вместо преимущества. Я имею в виду, что все аргументы функции помещаются в стек по порядку, чтобы функция могла их прочитать, и это будет либо ваш int, либо его адрес в случае ссылки. Другой недостаток заключается в том, что вызываемый будет либо обращаться к вашему n через косвенное обращение (разыменование адреса), либо сделает копию в своем стеке для оптимизации.

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

1
ответ дан 4 December 2019 в 06:26
поделиться
0
ответ дан 4 December 2019 в 06:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: