我从this answer中学到了在 C# 中的 for 和 while 循环中:“只要您使用 arr.Length,编译器/JIT 就会针对这种情况进行优化> 在条件:"
for(int i = 0 ; i < arr.Length ; i++) {
Console.WriteLine(arr[i]); // skips bounds check
}
这让我想知道 java 编译器是否有这样的优化。
for(int i=0; i<arr.length; i++) {
System.out.println(arr[i]); // is bounds check skipped here?
}
我认为是的,嗯,是吗?使用像 ArrayList 这样的 Collection 时会发生同样的情况吗?
但是,如果我必须在 for 循环的主体内使用 myList.size() 的值,现在考虑 myList 怎么办?成为一个 ArrayList?所以在那种情况下,提升 myList.size() 不会有帮助,因为 size() 是一个方法调用?例如可能是这样的:
int len = myList.size(); // hoisting for using inside the loop
for(int i = 0; i < myList.size(); i++) { // not using hoisted value for optimization
System.out.println(myList.get(i));
if(someOtherVariable == len) {
doSomethingElse();
}
}
编辑: 虽然我还没有得到 java 的答案,但我仍在为这个问题添加第二部分。
问: C++ (C++98/C++11) 是否有这样的优化,例如对于vector.size()和 string.size() ?例如,哪个性能更好?
for (int i = 0; i < myvector.size(); ++i)
cout << myvector[i] << " "; // is bounds checking skipped here, like in C#?
或
// does this manual optimisation help improve performance, or does it make?
int size = myvector.size();
for (int i = 0; i < size; ++i)
cout << myvector[i] << " ";
也就是说,std::string 是否存在这样的优化?还有吗?
最佳答案
从 Java 7 开始,如果编译器可以证明越界访问是不可能的,则编译器将消除对原始数组的边界检查。在 Java 7 之前,JIT 或 AOT 编译器可以做到这一点。对于 JIT 和 AOT 编译器,它不限于 for (int i = 0; i < arr.length; i++) ,它可以将边界检查移到循环之外,例如 for (int i = 0; i < 10000000; i++) ,将其减少为单张支票。如果该检查失败,它将运行具有完整边界检查的代码版本,以在正确的位置抛出异常。
对于集合来说要复杂得多,因为边界是由被调用的方法检查的,而不是在调用的地方。通常,它不能从字节码中消除,但 JIT 和 AOT 编译器可以消除它,如果它们可以内联方法(这取决于对象的实例化方式和存储位置等,因为 Java 中的所有非私有(private)方法是虚拟的,因此编译器需要确保它不需要虚拟调用)但我不知道它们是否真的需要。
C++ 不检查 operator [] 中的边界.当您使用 at 时它会检查边界. at是内联的,因此它取决于特定的编译器及其标志,但通常,编译器可以删除边界检查,如果它可以证明越界访问是不可能的。它还可以将边界检查移到循环之外,但它仍然需要保证异常将在正确的位置抛出,所以我不知道是否有异常。
假设您不使用 int size,这两个 C++ 示例在执行死代码消除的编译器中将是等效的在for之后环形。如果您使用一些未内联的方法,后者可能会更快。 (也可以把size的定义放在初始化里面:for (int i = 0, size = myvector.size(); i < size; ++i))
关于java - Java 和 C++ 中 for 循环边界检查的编译器/JIT 优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35387763/
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
似乎无法为此找到有效的答案。我正在阅读Rails教程的第10章第10.1.2节,但似乎无法使邮件程序预览正常工作。我发现处理错误的所有答案都与教程的不同部分相关,我假设我犯的错误正盯着我的脸。我已经完成并将教程中的代码复制/粘贴到相关文件中,但到目前为止,我还看不出我输入的内容与教程中的内容有什么区别。到目前为止,建议是在函数定义中添加或删除参数user,但这并没有解决问题。触发错误的url是http://localhost:3000/rails/mailers/user_mailer/account_activation.http://localhost:3000/rails/mai
当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我