草庐IT

c++ - 在哪里为最高效的代码定义一次性常量?

coder 2024-02-12 原文

哪种变体最有效,为什么?或者它们会针对相同的代码进行优化吗?

char inplace(int i) {
    // [some check if 0<=i<=2 here]
    return "azS"[i];
}

char infunc(int i) {
    const char s[] = "azS";
    // [some check if 0<=i<sizeof(s)/sizeof(s[0])-1 here]
    return s[i];
}

const char s[] = "azS";
char inglobals(int i) {
    // [some check if 0<=i<sizeof(s)/sizeof(s[0])-1 here]
    return s[i];
}

请不要提示过早的优化是多么邪恶,这只是天生的 C++ 人与生俱来的不可抗拒的好奇心 ;)

最佳答案

我刚刚编译和反汇编了你的代码。 inplaceinglobals 是相同的。这非常直观:编译器可以将常量字符串存储在 .rodata 部分。

奇怪的是,gcc 为 infunc 生成了很多代码(见下文),这可能是因为您“坚持”要在堆栈上放置 s。将 s 定义为 static 会使 infunc 生成与 inplaceinglobals 相同的代码。

0000000000000010 :
  10:   48 83 ec 18             sub    $0x18,%rsp
  14:   48 63 ff                movslq %edi,%rdi
  17:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
  1e:   00 00 
  20:   48 89 44 24 08          mov    %rax,0x8(%rsp)
  25:   31 c0                   xor    %eax,%eax
  27:   c7 04 24 61 7a 53 00    movl   $0x537a61,(%rsp)
  2e:   0f b6 04 3c             movzbl (%rsp,%rdi,1),%eax
  32:   48 8b 54 24 08          mov    0x8(%rsp),%rdx
  37:   64 48 33 14 25 28 00    xor    %fs:0x28,%rdx
  3e:   00 00 
  40:   75 05                   jne    47 
  42:   48 83 c4 18             add    $0x18,%rsp
  46:   c3                      retq   
  47:   e8 00 00 00 00          callq  4c 

编辑

位置 %fs:0x28 与 GCC 的堆栈保护器有关。禁用它给出以下代码:

0000000000000010 :
  10:   48 63 ff                movslq %edi,%rdi
  13:   c7 44 24 f0 61 7a 53    movl   $0x537a61,-0x10(%rsp)
  1a:   00 
  1b:   0f b6 44 3c f0          movzbl -0x10(%rsp,%rdi,1),%eax
  20:   c3                      retq   

因此,在这种情况下,GCC 选择将您的字符串与代码内联存储,并在执行期间将其复制到堆栈中。我认为这是非常有效的,因为你的处理器的缓存已经充满了字符串,所以不会发生内存访问。

编辑

综上所述,三个版本都是等价的。然而,根据您的编译器实现,一个可能比另一个更有效。对于 GCC,infunc 对于短字符串似乎更有效,因为字符串是随指令一起获取的。对于较大的字符串,我会使用 inplaceinglobals

关于c++ - 在哪里为最高效的代码定义一次性常量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12212673/

有关c++ - 在哪里为最高效的代码定义一次性常量?的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  3. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  4. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  5. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

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

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

  7. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

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

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

  9. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  10. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

随机推荐