constexpr 说明符性能没有达到我在 C++ 中的期望

Posted

技术标签:

【中文标题】constexpr 说明符性能没有达到我在 C++ 中的期望【英文标题】:constexpr specifier performance didn't meet my expectations in C++ 【发布时间】:2018-10-07 03:30:18 【问题描述】:

我刚刚了解到constexpr说明符函数可以在编译过程中运行,我尝试用Debug x86 Mode检查VS 2017的实际性能,结果显示它们之间的时间差异很小。它仍然经过了很多时间,而不是“0”。我是不是做错了什么,谁能帮帮我,非常感谢!

#include <iostream>
#include <time.h>

size_t r_fun(size_t n) noexcept

    if (n == 0) return 0;
    if (n == 1) return 1;
    return r_fun(n - 1) + r_fun(n - 2);


constexpr size_t c_fun(size_t n) noexcept

    if (n == 0) return 0;
    if (n == 1) return 1;
    return c_fun(n - 1) + c_fun(n - 2);



int main()

    clock_t start, finish;

    start = clock();
    auto r_x = r_fun(40);  
    finish = clock();
    std::cout <<"result:"<< r_x<< "\ttime:" << (double)(finish - start) << std::endl;

    start = clock();
    static const auto c_x = c_fun(40);
    finish = clock();
    std::cout << "result:" << c_x << "\ttime:" << (double)(finish - start) << std::endl;

    return 0;

【问题讨论】:

actual performance in VS 2017 with Debug x86 Mode, 在调试模式下不检查性能。 constexpr 不存在以提高性能。因此,在这种情况下它并没有提高性能(即使忽略调试构建)这一事实并不是该功能或其实现的问题。 【参考方案1】:

您的 constexpr 函数需要在编译器中进行太多计算,这就是编译器选择将其延迟到运行时执行的原因。

你可以改变这一行:

static const auto c_x = c_fun(40);

到:

constexpr auto c_x = c_fun(40);

查看编译器的输出。在铿锵声中,它告诉我:

note: constexpr evaluation hit maximum step limit;

c_x 确实是一个编译时常量,但由于实现限制,编译器无法计算它。请注意,您的函数具有指数级复杂性。

Everything will be fine 如果你将 40 更改为某个合理的数字,比如 10:

constexpr auto c_x = c_fun(10);

【讨论】:

即使是 40 岁的编译器也可以毫无问题地解决这个问题。例如g++ 8.1,显然可以归结为最终答案。这完全取决于您使用的工具链及其施加的限制。 @WhozCraig 对于clang,这个限制不能被选项覆盖,-fconstexpr-steps 选项的类型是int,这个函数需要long 步骤。 github.com/llvm-mirror/clang/blob/master/lib/Frontend/…。但总而言之,它依赖于实现。

以上是关于constexpr 说明符性能没有达到我在 C++ 中的期望的主要内容,如果未能解决你的问题,请参考以下文章

解读C++ constexpr关键字的特性

C++中 const和constexpr的区别

C++中 const和constexpr的区别

C ++ constexpr最终虚函数[重复]

将函数指针分配给 constexpr 结构中的 typedef 函数的正确 C++ 方法是啥?

C++ 编译器优化 - 为啥需要 constexpr?