Compile time evaluation and performance

Hi all,

In this piece of code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

constexpr double nth(double x, int n) // assume 0<=n
{
  double res = 1;
  int i = 0;
  
   while (i<n) {
   res*=x;
   ++i;
  }
 
return res;
}

int main()
{
   std::cout << nth(2, 5);
   return 0;
}

since the function is defined using constexpr and the values of the parameters are clear for the compiler (2, 5) before entering into run-time, then the output is given at compile-time, hence we may have a little performance enhancement compared to the time we omit the keyword constexpr. Right?
Last edited on
Not necessarily. It's entirely up to the compiler to try and evaluate/optimize the function call at compile time.

If you change the code in main to ...

1
2
constexpr double res = nth(2, 5);
std::cout << res;

... then you're essentially guaranteed it will be evaluated at compile time.
Last edited on
I'm not sure of being quite aware of the difference with that change.

Yet, if we change the code a little more
1
2
3
4
5
6
7
8
9
10
11
int main() {

   int n {0};
   double d {0};
   std::cin >> n >> d;

   constexpr double res = nth(n, d);
   std::cout << res;

   return 0;
}

the output is not produced at compile-time, but run-time. Yeah?
Last edited on
Your latest code snippet gives a compilation error because nth(n, d) can't be evaluated at compile-time.

Marking the function constexpr might influence the compiler's choice to evaluate/optimize the function at compile time but it's not a guarantee unless you call it from a constexpr context (e.g. when using the function return value to initialize a constexpr variable, specify the size of static array or to use as a template argument; or when calling the function from another constexpr function that has been called from such a constexpr context).
Last edited on
This will evaluate at compile time - as static_assert returns true:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

constexpr double nth(double x, unsigned n) {
	double res {x};

	if (x > 1)
		for (unsigned i {}; i < n - 1; ++i)
			res *= x;

	return res;
}

int main() {
	static_assert (nth(2, 5) == 32);
}


However, if the values of the args for nth can't be determined at compile time, then it will be evaluated at run-time
Yes, static_assert is a constexpr context. The expression needs to be evaluated at compile time so therefore it is.
Last edited on
Since C++20 there is also consteval which will cause an error if the function cannot produce a compile-time evaluation (ie an error if can only be evaluated at run-time).
Instead of:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

constexpr double nth(double x, int n) // assume 0<=n
{
  double res = 1;
  int i = 0;
  
   while (i++<n) 
   res*=x;
 
return res;
}

int main() {
   constexpr double res = nth(2, 5);
   std::cout << res;

   return 0;
}


we could write :

1
2
3
4
5
6
7
#include <iostream>
int main() {

   std::cout << 32;

   return 0;
}

What's the difference between these two in effect, please?
What is the benefit of constexpr?
frek wrote:
What is the benefit of constexpr?

C++ constexpr makes compile-time programming a breeze
https://iamsorush.com/posts/cpp-constexpr/

Using constexpr to Improve Security, Performance and Encapsulation in C++
https://smartbear.com/blog/using-constexpr-to-improve-security-performance-an/

From the metasearch:
https://duckduckgo.com/?q=c%2B%2B+benefit+of+constexpr&t=ffsb&ia=web
What is the benefit of constexpr?

It provides a way to reliably guarantee static initialization and compile-time evaluation without relying on the (implementation-dependent, unreliable) compiler optimizer.

const alone doesn't do this. If the initializer for a const variable is not a constant expression, the compiler will fall back to dynamic initialization. Depending on the initializer, the process of dynamic initialization can require arbitrary amounts of time and space.

It is desirable to have a guarantee that such expensive processes are not performed at run-time, and this guarantee is what constexpr offers.

S.A.: https://web.archive.org/web/20170809144609/http://www.axiomatics.org/~gdr/constants/constexpr-sac10.pdf
Last edited on
Topic archived. No new replies allowed.