为什么在运行时而不是在编译时评估使用constexpr初始化变量

伊夫

据我了解,该关键字constexpr告诉编译器对表达式的求值可以在编译时进行。具体来说,constexpr在变量上意味着可以在编译时评估变量的值,而constexpr在函数上意味着可以在编译时调用此函数并评估其返回值。如果在运行时调用该功能,则它仅充当通用功能。

今天,我写了一段代码尝试使用constexpr

#include <iostream>

using namespace std;

constexpr long int fib(int n)
{
    return (n <= 1)? n : fib(n-1) + fib(n-2);
}

int main ()
{
    constexpr long int res = fib(32);
    // const long int res = fib(32);
    
    cout << res << endl;
    return 0;
}

我原以为代码的编译会花费很多时间,但是我错了。只需花费0.0290s来进行编译:

$ time g++ test.cpp
real    0m0.290s
user    0m0.252s
sys     0m0.035s

但是,如果我更改constexpr long int res = fib(32);const long int res = fib(32);,令我惊讶的是,它在编译上花费了更多时间:

$ time g++ test.cpp
real    0m5.830s
user    0m5.568s
sys     0m0.233s

简而言之,似乎 const使函数fib(32)在编译时进行评估,但constexpr使它在运行时进行评估。我真的很困惑

我的系统:Ubuntu 18.04

我的gcc:g ++(Ubuntu 7.5.0-3ubuntu1〜18.04)7.5.0

生锈的

通过检查生成的程序集,我们可以确认在两种情况下, G ++ 7.5都fib(32)在编译时计算了该值:

    movl    $2178309, %esi

其原因G ++评估constexpr上下文如此之快是由于记忆化其评估时执行constexprtemplate上下文。

记忆化将斐波那契的计算复杂度降低到O(N)复杂度,从而彻底消除了斐波那契的计算复杂度。

那么,为什么不constexpr评估这么慢呢?我认为这是优化程序中的错误/缺点。如果我尝试使用G ++ 8.1或更高版本,则编译时间没有差异,因此大概已经解决了。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么BufferedReader类在编译时而不是在运行时产生异常

来自分类Dev

为什么Swift中的反向范围会在运行时而不是编译时崩溃

来自分类Dev

对于汇编/C 中的变量,为什么要使用 .data 而不是在 .bss 中保留空间并在运行时初始化?

来自分类Dev

类内成员初始化是在编译时还是在运行时进行?

来自分类Dev

为什么`to_unsigned(0,4)> = -1`在运行时评估为“ FALSE”?

来自分类Dev

使用自动布局,后台UIView在运行时而不是设计时隐藏内容。为什么?

来自分类Dev

为什么未初始化的constexpr变量不是常量?

来自分类Dev

在编译时VS运行时初始化链表或工作队列

来自分类Dev

在编译时VS运行时初始化链表或工作队列

来自分类Dev

概括编译时和运行时评估

来自分类Dev

如何使用Datatable的Compute方法在运行时评估布尔表达式?

来自分类Dev

在运行时初始化依赖项

来自分类Dev

在运行时初始化unique_ptr

来自分类Dev

在运行时初始化数组元素

来自分类Dev

在运行时初始化依赖项

来自分类Dev

确定`constexpr`执行-是在编译期间还是在运行时?

来自分类Dev

为什么我会得到警告:(在指向“ ptr”的初始化附近)并且在运行时在指针处赋值时出现分段错误?

来自分类Dev

为什么我可以在运行时通过 ClassName.__init__(self) 初始化另一个类来扩展一个类

来自分类Dev

实现在应用程序启动时而不是在编译时初始化的“常量”类

来自分类Dev

防止运行时评估

来自分类Dev

为什么窗口在设计时而不是运行时显示样式

来自分类Dev

为什么在执行或运行时而不是在解析时设置IDENTITY_INSERT?

来自分类Dev

以编程方式确定变量的值是在编译时还是在运行时计算的

来自分类Dev

为什么constexpr函数可以与在运行时生成的变量一起很好地工作?

来自分类Dev

g ++编译数组,数组大小在运行时由const值(不是constexpr)给定

来自分类Dev

如何使MSVC 14在编译时评估我的constexpr

来自分类Dev

在运行时评估groovy字符串表达式

来自分类Dev

内联帮助方法如何以及为何在运行时评估类型?

来自分类Dev

如何在运行时使用构造函数初始化类中私有的数组?

Related 相关文章

  1. 1

    为什么BufferedReader类在编译时而不是在运行时产生异常

  2. 2

    为什么Swift中的反向范围会在运行时而不是编译时崩溃

  3. 3

    对于汇编/C 中的变量,为什么要使用 .data 而不是在 .bss 中保留空间并在运行时初始化?

  4. 4

    类内成员初始化是在编译时还是在运行时进行?

  5. 5

    为什么`to_unsigned(0,4)> = -1`在运行时评估为“ FALSE”?

  6. 6

    使用自动布局,后台UIView在运行时而不是设计时隐藏内容。为什么?

  7. 7

    为什么未初始化的constexpr变量不是常量?

  8. 8

    在编译时VS运行时初始化链表或工作队列

  9. 9

    在编译时VS运行时初始化链表或工作队列

  10. 10

    概括编译时和运行时评估

  11. 11

    如何使用Datatable的Compute方法在运行时评估布尔表达式?

  12. 12

    在运行时初始化依赖项

  13. 13

    在运行时初始化unique_ptr

  14. 14

    在运行时初始化数组元素

  15. 15

    在运行时初始化依赖项

  16. 16

    确定`constexpr`执行-是在编译期间还是在运行时?

  17. 17

    为什么我会得到警告:(在指向“ ptr”的初始化附近)并且在运行时在指针处赋值时出现分段错误?

  18. 18

    为什么我可以在运行时通过 ClassName.__init__(self) 初始化另一个类来扩展一个类

  19. 19

    实现在应用程序启动时而不是在编译时初始化的“常量”类

  20. 20

    防止运行时评估

  21. 21

    为什么窗口在设计时而不是运行时显示样式

  22. 22

    为什么在执行或运行时而不是在解析时设置IDENTITY_INSERT?

  23. 23

    以编程方式确定变量的值是在编译时还是在运行时计算的

  24. 24

    为什么constexpr函数可以与在运行时生成的变量一起很好地工作?

  25. 25

    g ++编译数组,数组大小在运行时由const值(不是constexpr)给定

  26. 26

    如何使MSVC 14在编译时评估我的constexpr

  27. 27

    在运行时评估groovy字符串表达式

  28. 28

    内联帮助方法如何以及为何在运行时评估类型?

  29. 29

    如何在运行时使用构造函数初始化类中私有的数组?

热门标签

归档