在调试模式下编译constexpr函数的编译时间

时间:2014-03-04 20:22:41

标签: c++ c++11 compiler-construction metaprogramming constexpr

我一直在使用以下代码段来理解constexpr

#include <stdlib.h>

///////////////////
bool runtimeIsPalindrome(const char* s, int len)
{
  if(len < 2)
    return true;
  else
    return s[0] == s[len-1] && runtimeIsPalindrome(&s[1], len-2);
}

///////////////////
constexpr bool compileTimeIsPalindrome(const char* s, int len)
{
    return len < 2 ? true : s[0] == s[len-1] && compileTimeIsPalindrome(&s[1], len-2);
}

///////////////////
int main()
{
    constexpr char c[] = "helloworlddlrowolleh";
    for(size_t nn=0;nn<1e8; ++nn) {
        // static_assert(compileTimeIsPalindrome(c, sizeof(c)-1 ), "Blah");
        // compileTimeIsPalindrome(c, sizeof(c)-1 );
        // runtimeIsPalindrome( c, sizeof(c)-1 );
    }
}

使用runtimeIsPalindrome版本...

clear; g++ -std=c++11 plaindrome.cpp; time ./a.out 
real    0m8.333s
user    0m8.322s
sys     0m0.005s

使用compileTimeIsPalindrome版本...

clear; g++ -std=c++11 plaindrome.cpp; time ./a.out
real    0m8.257s
user    0m8.247s
sys     0m0.004s

...但是对于static_assert(compileTimeIsPalindrome版本,我实际上似乎观察了一些编译时间的魔法......

clear; g++ -std=c++11 plaindrome.cpp; time ./a.out
real    0m0.265s
user    0m0.263s
sys     0m0.001s

为什么编译时评估仅在我在此示例中尝试断言时才起作用?

注意:对于此示例,任何优化的分析似乎都没有意义,因为看起来编译器发现结果是恒定的,而不管循环中调用的函数是否给出了与上面最快的概要时间相似的时序。

1 个答案:

答案 0 :(得分:3)

constexpr不保证编译时评估,除非在static_assert,模板参数或任何其他需要在编译时通过语言规则知道值的地方使用。

斐波纳契系列f(n) = f(n - 1) + f(n - 2), f(0) = f(1) = 1就是一个很好的例子。在我的机器上使用gcc,对于n <= 10,这个get在编译时被评估。对于任何其他参数,编译器被允许 - 实际上 - 确定它计算量太大并且默认为运行时评估。