草庐IT

java - 定义的参数评估顺序导致次优代码?

coder 2024-02-08 原文

众所周知,c 和 c++ 中的参数求值顺序没有定义: 例如:foo(a(),b()) 在上面的调用中,由编译器的实现来决定选择哪个求值顺序以及首先执行哪个函数。最近我的一位 friend 问为什么在 C 或 C++ 中未指定求值顺序。当我用谷歌搜索时,我开始知道指定评估顺序会导致次优代码生成。但怎么会这样呢?为什么定义的参数评估顺序会导致次优代码?当我提到 Java 的参数评估顺序时。我在规范中发现了以下内容。

15.7.4. Argument Lists are Evaluated Left-to-Right

In a method or constructor invocation or class instance creation expression, argument expressions may appear within the parentheses, separated by commas. Each argument expression appears to be fully evaluated before any part of any argument expression to its right. If evaluation of an argument expression completes abruptly, no part of any argument expression to its right appears to have been evaluated?

在这种情况下,Java 有一个定义的参数评估顺序,但是如果指定这样的行为,说 C 或 C++ 编译器会产生次优代码似乎有点奇怪。你能解释一下吗?

最佳答案

部分历史:在寄存器很少的处理器上,对于 例如,一种传统(且简单)的优化技术是 首先评估需要最多寄存器的子表达式。如果一个 子表达式需要5个寄存器,另外4个,比如你 可以将需要5的结果保存在不需要的寄存器中 由需要 4 的那个。

这可能没有通常认为的那么重要。编译器可以 如果表达式没有副作用,则重新排序(即使在 Java 中),或者 重新排序不会改变程序的可观察行为。 现代编译器能够比编译器更好地确定这一点 二十多年前(制定 C++ 规则时)。和 据推测,当他们无法确定这一点时,您已经做得足够了 在每个表达式中,额外溢出到内存并不重要。

至少,这是我的直觉。至少有一个人告诉过我 谁真正在优化器上工作,这将产生重大影响 差异,所以我不会说我确定。

编辑:

只是添加一些关于 Java 模型的评论。 Java 的时候 在设计时,它被设计为一种解释性语言。极端 性能不是问题;目标是极度安全,并且 再现性。因此,它非常精确地指定了很多东西,所以 任何编译的程序都将具有完全相同的行为 无论平台如何。应该没有未定义的 行为,没有实现定义的行为,也没有未指定的 行为。无论成本如何(但相信这可能是 在任何最普遍的机器上以合理的成本完成)。一 C(和间接的 C++)的初始设计目标是不必要的 额外的运行时成本应该是最小的,平台之间的一致性 不是目标(因为在当时,即使是常见的平台也各不相同 大大),而这种安全虽然令人担忧,但并不是最重要的。尽管 态度发生了一些变化,仍然有一个目标能够 有效地支持可能存在的任何机器。没有 需要最新、最复杂的编译器技术。而不同 目标自然会导致不同的解决方案。

关于java - 定义的参数评估顺序导致次优代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11450093/

有关java - 定义的参数评估顺序导致次优代码?的更多相关文章

  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 - 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

  4. 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

  5. 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您的程序将作为解释器的子进程执行。除

  6. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  7. 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,如果没有检查,请帮助我,非常感谢,谢谢

  8. 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

  9. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  10. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

随机推荐