Изменение нормальной функции на шаблон будет иметь положительное / отрицательное значение? - PullRequest
1 голос
/ 23 мая 2011

У меня есть функция-оболочка (шаблонизированная) Outer() и базовая функциональность как Inner().

namespace N
{
  A* Inner (void *p, int value, const int ID);

  template<typename T>
  A* Outer (T *p, const int ID)  // ID is a compile time constant
  {
    return Inner (p, p->value, ID);
  }
}

Использование:

A *px = Outer(new X(3), 12345);
A *py = Outer(new Y(4), 987);

Мне удалось передать константу времени компиляции как ID. Итак, я думаю об изменении Outer() прототипа на

template<int ID, typename T>
A* Outer (T *p)
{
  return Inner (p, p->value, ID);
}

Который будет использоваться как,

A *pz = Outer<333>(new Z(5));

Хотелось бы знать, есть ли влияние кода / уровня производительности с новым подходом? Будет ли влиять на встраивание ?

Редактировать : идентификатор обязательно во время компиляции, и есть несколько случаев появления Outer() (поэтому важно знать и о inline).

Ответы [ 4 ]

3 голосов
/ 23 мая 2011

Прежде всего, так как ID должен быть int, шаблон должен быть

template<int ID, typename T>
A* Outer (T *p)
...

Продолжая, однако, что касается взлетов и падений, это отчасти зависит от вашего использования, но вот некоторые достоверные факты:

Производительность

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

Использование

Две формы действительно не эквивалентны. Поскольку определение функции определяется во время компиляции в зависимости от значения ID, можно использовать только константы времени компиляции (что, по-видимому, вы ожидаете). В оригинальной версии пользователь мог написать

int i = 10;
Outer<Z>(new Z(5), i);

Хотя i является переменной, она копируется в ID как постоянное значение.

В шаблонной версии они не могут писать

int i = 10;
Outer<i, Z>(new Z(5));

Поскольку компилятор генерирует различную функцию для каждого значения ID, он не может создать функцию во время компиляции, когда значение не известно до времени выполнения

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

Скомпилированный код

Для скомпилированного кода ваш двоичный файл будет больше (при условии, что вы используете функцию как минимум для двух разных значений ID). Это связано с тем, что для каждого отдельного значения идентификатора, который используется в программе, создается новая функция. Так что, если вы ожидаете, что будет использоваться много разных значений, раздувание в вашем двоичном коде может стать проблемой

Встраивание

Это то, на что у меня нет однозначного ответа. Я предполагаю, что если это повлияет на встраивание, скорее всего, на него повлияет параметр T, а не ID.

1 голос
/ 23 мая 2011

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

0 голосов
/ 23 мая 2011

Это будет зависеть от вашего компилятора и от того, как используются функции. На практике, если у вас есть оптимизация, единственным Разница, я думаю, вы увидите в синтаксисе вызова. Но если у вас есть проблемы с производительностью, профиль и посмотреть, где это Исходя из.

0 голосов
/ 23 мая 2011

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

Вы можете сказать: «У меня супер быстрый компьютер, а компиляция занимает 1/2 секунды», но для больших проектов это имеет большое значение.

...