g++ (4.7.2) 和类似版本似乎在编译时评估 constexpr 的速度出奇地快。在我的机器上实际上比运行时编译的程序快得多。
这种行为有合理的解释吗?是否涉及仅适用于编译时的优化技术,可以比实际编译的代码更快地执行?如果是这样,是哪个?
这是我的测试程序和观察到的结果。
#include <iostream>
constexpr int mc91(int n)
{
return (n > 100)? n-10 : mc91(mc91(n+11));
}
constexpr double foo(double n)
{
return (n>2)? (0.9999)*((unsigned int)(foo(n-1)+foo(n-2))%100):1;
}
constexpr unsigned ack( unsigned m, unsigned n )
{
return m == 0
? n + 1
: n == 0
? ack( m - 1, 1 )
: ack( m - 1, ack( m, n - 1 ) );
}
constexpr unsigned slow91(int n) {
return mc91(mc91(foo(n))%100);
}
int main(void)
{
constexpr unsigned int compiletime_ack=ack(3,14);
constexpr int compiletime_91=slow91(49);
static_assert( compiletime_ack == 131069, "Must be evaluated at compile-time" );
static_assert( compiletime_91 == 91, "Must be evaluated at compile-time" );
std::cout << compiletime_ack << std::endl;
std::cout << compiletime_91 << std::endl;
std::cout << ack(3,14) << std::endl;
std::cout << slow91(49) << std::endl;
return 0;
}
编译时间:
time g++ constexpr.cpp -std=c++11 -fconstexpr-depth=10000000 -O3
real 0m0.645s
user 0m0.600s
sys 0m0.032s
运行:
time ./a.out
131069
91
131069
91
real 0m43.708s
user 0m43.567s
sys 0m0.008s
这里 mc91 是通常的 mac carthy f91(可以在 wikipedia 上找到),而 foo 只是一个返回大约 1 到 100 之间的实际值的无用函数,具有 fib 运行时复杂性。
91 的慢速计算和 ackermann 函数都由编译器和编译程序使用相同的参数进行评估。
令人惊讶的是,该程序甚至会运行得更快,只需生成代码并通过编译器运行它,而不是执行代码本身。