J'ai essayé des expressions const qui sont évaluées au moment de la compilation. Mais j'ai joué avec un exemple qui semble incroyablement rapide lorsqu'il est exécuté au moment de la compilation.
#include<iostream>
constexpr long int fib(int n) {
return (n <= 1)? n : fib(n-1) + fib(n-2);
}
int main () {
long int res = fib(45);
std::cout << res;
return 0;
}
Lorsque j'exécute ce code, l'exécution prend environ 7 secondes. Jusqu'ici tout va bien. Mais quand je change long int res = fib(45)
de const long int res = fib(45)
trajet ne dure pas même une seconde. À ma connaissance, il est évalué au moment de la compilation.
Mais la compilation prend environ 0,3 seconde
Comment le compilateur peut-il évaluer cela si rapidement, mais au moment de l'exécution, cela prend beaucoup plus de temps? J'utilise gcc 5.4.0.
fib
. La mise en œuvre des nombres de fibonacci que vous avez ci-dessus est assez lente. Essayez de mettre en cache les valeurs des fonctions dans le code d'exécution et cela sera beaucoup plus rapide.Réponses:
Le compilateur met en cache des valeurs plus petites et n'a pas besoin de recalculer autant que la version d'exécution.
(L'optimiseur est très bon et génère beaucoup de code, y compris la ruse avec des cas spéciaux qui me sont incompréhensibles; les récursions naïves de 2 ^ 45 prendraient des heures.)
Si vous stockez également des valeurs précédentes:
la version d'exécution est beaucoup plus rapide que le compilateur.
la source
fib
fonction donnée n'a pas d'effets secondaires (ne fait référence à aucune variable externe, la sortie dépend uniquement des entrées), avec un optimiseur intelligent, beaucoup peut être fait.Vous pouvez trouver intéressant avec 5.4 la fonction n'est pas complètement éliminée, vous avez besoin d'au moins 6.1 pour cela.
Je ne pense pas qu'il y ait de mise en cache. Je suis convaincu que l'optimiseur est suffisamment intelligent pour prouver la relation entre
fib(n - 2)
etfib(n-1)
et évite complètement le deuxième appel. Il s'agit de la sortie GCC 5.4 (obtenue à partir de godbolt) sansconstexpr
et -O2:Je dois admettre que je ne comprends pas la sortie avec -O3 - le code généré est étonnamment complexe, avec beaucoup d'accès à la mémoire et l'arithmétique des pointeurs et il est fort possible qu'il y ait une mise en cache (mémorisation) effectuée avec ces paramètres.
la source