Допустим, у меня есть следующий metafunction:Оптимизация производительности во время компиляции с помощью кэширования метафункции
template <typename T>
struct make_pair {
using type = std::pair<
typename std::remove_reference<T>::type,
typename std::remove_reference<T>::type
>;
};
Будет ли это улучшить скорость компиляции, чтобы сделать это (или что-то еще) вместо?
template <typename T>
struct make_pair {
using without_reference = typename std::remove_reference<T>::type;
using type = std::pair<without_reference, without_reference>;
};
Я вижу две возможности:
Компилятор должен сделать некоторую работу каждый раз, когда он видит
typename std::remove_reference<T>::type
. Использование промежуточного псевдонима имеет какое-то «кэширование» поведения, которое позволяет компилятору выполнять некоторую работу только один раз.Измерение времени компиляции измеряется с точки зрения количества экземпляров шаблонов, которые должен выполнять компилятор. Поскольку
std::remove_reference<T>::type
относится к тому же типу, что иstd::remove_reference<T>::type
, в обоих случаях требуется только один экземпляр шаблона, поэтому обе реализации эквивалентны производительности времени компиляции WRT.
Я думаю, что В является правильным, но я хотел бы быть уверен. Если ответ окажется специфичным для компилятора, мне бы в основном было интересно узнать ответ для Clang и GCC.
Edit:
Я протестированные составление тестовой программы, чтобы иметь некоторые данные для работы. Тестовая программа делает что-то вроде этого:
template <typename ...> struct result;
template <typename T>
struct with_cache {
using without_reference = typename std::remove_reference<T>::type;
using type = result<without_reference, ..., without_reference>;
};
template <typename T>
struct without_cache {
using type = result<
typename std::remove_reference<T>::type,
...,
typename std::remove_reference<T>::type
>;
{ };
using Result = with[out]_cache<int>::type;
Это среднее время для 10 компиляций программы, с 10 000 параметров шаблона в result<>
.
-------------------------
| g++ 4.8 | clang++ 3.2 |
-----------------------------------------
| with cache | 0.1628s | 0.3036s |
-----------------------------------------
| without cache | 0.1573s | 0.3785s |
-----------------------------------------
Тестовая программа генерируется по имеющимся скриптам here.
Я думаю, что никакие предположения не могут заменить фактические измерения. Пожалуйста, разместите некоторые цифры времени, тогда мы сможем создать хорошую теорию, чтобы объяснить их. –
Я видел разговор о clang, который говорит, что они делают hashtables для экземпляров шаблонов вместо связанных списков. Я не знаю, с кем они сравнивались. –
Компилятор 'template', который не выполняет memoization, будет смехотворно медленным. – Yakk