Я пробовал константные выражения, которые оцениваются во время компиляции. Но я играл с примером, который кажется невероятно быстрым при исполнении во время компиляции.
#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;
}
Когда я запускаю этот код, требуется около 7 секунд для запуска. Все идет нормально. Но когда я перехожу long int res = fib(45)
на const long int res = fib(45)
это, не требуется даже секунды. Насколько я понимаю, он оценивается во время компиляции.
Но компиляция занимает около 0,3 секунды
Как компилятор может оценить это так быстро, но во время выполнения это занимает намного больше времени? Я использую GCC 5.4.0.
fib
. Реализация чисел Фибоначчи, которые у вас есть выше, идет медленно. Попробуйте кэшировать значения функций в коде времени выполнения, и это будет намного быстрее.Ответы:
Компилятор кэширует меньшие значения и не должен пересчитывать столько, сколько делает версия времени выполнения.
(Оптимизатор очень хорош и генерирует много кода, включая хитрости с особыми случаями, которые мне непонятны; наивные 2 ^ 45 рекурсии заняли бы часы.)
Если вы также сохраняете предыдущие значения:
версия во время выполнения намного быстрее, чем компилятор.
источник
fib
функция не имеет побочных эффектов (не ссылается на внешние переменные, вывод зависит только от входных данных), с умным оптимизатором многое можно сделать.В версии 5.4 может показаться интересным, что эта функция полностью не устранена, для этого вам нужно как минимум 6.1.
Я не думаю, что происходит кэширование. Я убежден , что оптимизатор достаточно умен , чтобы доказать связь между
fib(n - 2)
иfib(n-1)
и полностью исключает второй вызов. Это вывод GCC 5.4 (полученный из Godbolt) безconstexpr
и -O2:Я должен признать, что не понимаю вывод с -O3 - сгенерированный код удивительно сложен, с большим количеством обращений к памяти и арифметикой указателей, и вполне возможно, что с этими настройками выполняется некоторое кеширование (запоминание).
источник