jjzjj

c++ - constexpr 在运行时表现更差

coder 2024-02-13 原文

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

#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”的时间,因为它已经在编译时计算过了。

但令人惊讶的是,constexpr 计算比普通阶乘要花费更多的时间。 我试着关注 this问题,但我无法在我的上下文中理解答案。

请帮助我理解它。

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

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

V2:-

@rici 输入后,我确实将第 18 行更改为

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 是常量,编译器就会在编译时计算 factorialC

我在 Windows 上使用来自 MinGW32 的 g++ 4.9.3 版本

最佳答案

问题是某些constexpr 保证在编译时求值。关键字 constexpr 只是说它可以,但编译器也可以在运行时自由评估它,因为它认为合适。

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

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

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 还有一个标准库函数,std::integral_constant .您可以改用它。

关于c++ - constexpr 在运行时表现更差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39577829/

有关c++ - constexpr 在运行时表现更差的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  3. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  4. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  5. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  6. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  7. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  8. ruby-on-rails - 无法让 rspec、spork 和调试器正常运行 - 2

    GivenIamadumbprogrammerandIamusingrspecandIamusingsporkandIwanttodebug...mmm...let'ssaaay,aspecforPhone.那么,我应该把“require'ruby-debug'”行放在哪里,以便在phone_spec.rb的特定点停止处理?(我所要求的只是一个大而粗的箭头,即使是一个有挑战性的程序员也能看到:-3)我已经尝试了很多位置,除非我没有正确测试它们,否则会发生一些奇怪的事情:在spec_helper.rb中的以下位置:require'rubygems'require'spork'

  9. ruby-on-rails - before_filter 运行多个方法 - 2

    是否有可能:before_filter:authenticate_user!||:authenticate_admin! 最佳答案 before_filter:do_authenticationdefdo_authenticationauthenticate_user!||authenticate_admin!end 关于ruby-on-rails-before_filter运行多个方法,我们在StackOverflow上找到一个类似的问题: https://

  10. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

随机推荐