constexpr在运行时性能较差 [英] constexpr performing worse at runtime

查看:67
本文介绍了constexpr在运行时性能较差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了以下代码来测试constexpr阶乘评估与正常方式所花费的时间

I wrote the following code to test the time taken for a constexpr factorial to evaluate vs normal way

#include<iostream>
#include<chrono>

constexpr long int factorialC(long int x){  return x*(x <2?1 : factorialC(x-1));}
using ns = std::chrono::nanoseconds;
using get_time = std::chrono::steady_clock;
void factorial(long int x){
    long int suma=1;
    for(long int i=1; i<=x;i++)
    {
        suma=suma*i;

    }
    std::cout<<suma<<std::endl;
}

int main(){
    long int x = 13;

    std::cout<<"Now calling the constexpr"<<std::endl;
    auto start1 = get_time::now();
    std::cout<<factorialC(x)<<std::endl;
    auto end1 = get_time::now();

    std::cout<<"Now calling the normal"<<std::endl;
    auto start2 = get_time::now();
    factorial(x);
    auto end2 = get_time::now();
    std::cout<<"Elapsed time for constexpr is "<<std::chrono::duration_cast<ns>(end1-start1).count()
    <<" Elapsed time for normal is "<<std::chrono::duration_cast<ns>(end2-start2).count()<<std::endl;
}

运行代码时,我会得到

Now calling the constexpr                                                                                                   
1932053504                                                                                                                  
Now calling the normal                                                                                                      
1932053504                                                                                                                  
Elapsed time for constexpr is 81812 Elapsed time for normal is 72428  

但是 constexpr 应该花费将近"0"的时间,因为它已经在编译期间进行了计算.

But constexpr should take nearly "0" time because it has already been calculated during compilation time .

但是令人惊讶的是, constexpr 的计算比正常的阶乘需要更多的时间.我尝试遵循问题,但我无法理解我的答案语境.

But surprisingly constexpr calculation takes more time than a normal factorial to work. I have tried to follow this question, but I am not able understand the answer in my context.

请帮助我理解它.

我通过(文件名是constexpr.cpp)编译了代码

I compiled the code through (filename is constexpr.cpp)

g++ --std=c++11 constexpr.cpp   

V2:-

在输入@rici之后,我确实将行号18更改为

V2:-

after @rici input, I did change line number 18 to

const long int x =13;

现在的结果是

Now calling the constexpr                                                                                                   
1932053504                                                                                                                  
Now calling the normal                                                                                                      
1932053504                                                                                                                  
Elapsed time for constexpr is 114653 Elapsed time for normal is 119052  

似乎一旦我提到x是const,编译器就会在编译时计算 factorialC

It seems once I mentioned the x to be const, the compiler is calculating factorialC at compile time

我正在Windows上使用MinGW32的g.++的4.9.3版本

I am using 4.9.3 version of g++ from MinGW32 on windows

推荐答案

问题在于,不能保证在编译时对 constexpr 进行评估.关键字 constexpr 只是说它可以,但是编译器也可以在运行时随意评估它.

The problem is that something constexpr is not guaranteed to be evaluated at compile time. The keyword constexpr just says that it can, but the compiler is free to evaluate it at run time too, as it sees fit.

运行时间的差异可能是因为您1)做得不够(一次迭代没什么),2)递归不如迭代快(我认为,尽管差异很小).

The difference in run time is probably because you 1) aren't doing it enough (one iteration is nothing) and 2) recursion isn't as fast as iteration (I think, although the difference is minimal).

为了保证编译时评估,您将不得不在编译器必须在编译时对其进行评估的上下文中使用它,例如模板:

To guarantee compile time evaluation, you will have to use it in a context where the compiler has to evaluate it at compile time, something like a template for example:

template<unsigned long long n>
auto evaluate() { return n; }

//...
auto start1 = get_time::now();
std::cout << evaluate<factorialC(x)>() << std::endl; //factorialC is evaluted
                                                     //at compile timme
auto end1 = get_time::now();

还有一个用于 evaluate 的标准库函数, 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆