Diciamo che ho il seguente metafunction:Ottimizzazione delle prestazioni a tempo di compilazione da caching METAFUNCTIONS
template <typename T>
struct make_pair {
using type = std::pair<
typename std::remove_reference<T>::type,
typename std::remove_reference<T>::type
>;
};
Sarebbe migliorare la velocità di compilazione per fare questo (o qualcos'altro), invece?
template <typename T>
struct make_pair {
using without_reference = typename std::remove_reference<T>::type;
using type = std::pair<without_reference, without_reference>;
};
Vedo due possibilità:
Il compilatore ha a che fare un certo lavoro ogni volta che vede
typename std::remove_reference<T>::type
. L'uso di un alias intermedio ha un qualche tipo di comportamento di "caching", che consente al compilatore di fare del lavoro una sola volta.Le prestazioni in fase di compilazione vengono misurate in termini di numero di istanze del modello che il compilatore deve eseguire. Poiché
std::remove_reference<T>::type
si riferisce allo stesso tipo distd::remove_reference<T>::type
, in entrambi i casi è necessaria solo un'istanza di modello, pertanto entrambe le implementazioni sono equivalenti alle prestazioni di compilazione WRT.
Penso che B abbia ragione, ma mi piacerebbe esserne sicuro. Se la risposta risulta essere specifica del compilatore, sarei principalmente interessato a conoscere la risposta per Clang e GCC.
Edit:
I benchmark la compilazione di un programma di test di avere alcuni dati su cui lavorare. Il programma di test fa qualcosa di simile:
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;
Questi sono i tempi medi di 10 compilation del programma, con 10 000 parametri di modello in result<>
.
-------------------------
| g++ 4.8 | clang++ 3.2 |
-----------------------------------------
| with cache | 0.1628s | 0.3036s |
-----------------------------------------
| without cache | 0.1573s | 0.3785s |
-----------------------------------------
Il programma di test è generato da uno script disponibile here.
Penso che nessuna quantità di speculazione possa sostituire le misurazioni effettive. Si prega di postare alcune cifre temporali, quindi possiamo creare una bella teoria per spiegarle. –
Ho visto un discorso su clang che dice che creano hashtables per le istanze dei template invece degli elenchi collegati. Non so a chi si stessero paragonando. –
Un compilatore 'template' che non esegue la memoizzazione sarà ridicolmente lento. – Yakk