Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the C++ compiler evaluate recursive constexpr functions so quickly?

I've been learning about C++ constexpr functions, and I implemented a constexpr recursive function to find the nth fibonacci number.

#include <iostream> #include <fstream> #include <cmath> #include <algorithm> #include <vector>  constexpr long long fibonacci(int num) {     if (num <= 2) return 1;     return fibonacci(num - 1) + fibonacci(num - 2); }  int main() {     auto start = clock();     long long num = fibonacci(70);     auto duration = (clock() - start) / (CLOCKS_PER_SEC / 1000.);     std::cout << num << "\n" << duration << std::endl; } 

If I remove the constexpr identifier from the fibonacci() function, then fibonacci(70) takes a very long time to evaluate (more than 5 minutes). When I keep it as-is, however, the program still compiles within 3 seconds and prints out the correct result in less than 0.1 milliseconds.

I've learned that constexpr functions are evaluated at compile time, so this would mean that fibonacci(70) is calculated by the compiler in less than 3 seconds! However, it doesn't seem quite right that the C++ compiler would have such better calculation performance than C++ code.

My question is, does the C++ compiler actually evaluate the function between the time I press the "Build" button and the time the compilation finishes? Or am I misunderstanding the keyword constexpr?

EDIT: This program was compiled with g++ 7.5.0 with --std=c++17.

like image 608
ahskdjfk Avatar asked Dec 03 '20 23:12

ahskdjfk


People also ask

Are constexpr functions evaluated at compile time?

A constexpr function that is eligible to be evaluated at compile-time will only be evaluated at compile-time if the return value is used where a constant expression is required. Otherwise, compile-time evaluation is not guaranteed.

Is constexpr faster?

Try it on your code baseNot only will your code be faster and smaller, it'll be safer. Code marked constexpr can't bitrot as easily.

Does C have constexpr?

No, no such thing exists in C.

What is the benefit of constexpr?

A constexpr integral value can be used wherever a const integer is required, such as in template arguments and array declarations. And when a value is computed at compile time instead of run time, it helps your program run faster and use less memory.


1 Answers

constexpr functions have no side-effects and can thus be memoized without worry. Given the disparity in runtime the simplest explanation is that the compiler memoizes constexpr functions during compile-time. This means that fibonacci(n) is only computed once for each n, and all other recursive calls get returned from a lookup table.

like image 133
orlp Avatar answered Sep 30 '22 13:09

orlp