- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在学校被告知,修改 for 循环
的索引变量是一种不好的做法:
示例:
for(int i = 0 ; i < limit ; i++){
if(something){
i+=2; //bad
}
if(something){
limit+=2; //bad
}
}
争论的焦点是一些编译器优化可以优化循环,而不是在每个循环中重新计算索引和边界。
我在 java
中做了一些测试,似乎默认情况下每次都会重新计算索引和边界。
我想知道是否可以在 JVM HotSpot
中激活这种功能?
例如优化这种循环:
for(int i = 0 ; i < foo.getLength() ; i++){ }
无需编写:
int length = foo.getLength()
for(int i = 0 ; i < length ; i++){ }
这只是一个例子,我很想尝试看看改进。
编辑
根据 Peter Lawrey 的回答为什么在这个简单的例子中 JVM 不内联 getLength()
方法?:
public static void main(String[] args) {
Too t = new Too();
for(int j=0; j<t.getLength();j++){
}
}
class Too {
int l = 10;
public Too() {
}
public int getLength(){
//System.out.println("test");
return l;
}
}
在输出中“test”打印了 10 次。
我认为优化这种执行可能会很好。
编辑 2:看来我误会了...
我已经删除了 println
,实际上分析器告诉我在这种情况下方法 getLength()
甚至没有被调用一次。
最佳答案
I've made some test in java and it seems that by default index and bound are recalculate each time.
根据 Java 语言规范,这:
for(int i = 0 ; i < foo.getLength() ; i++){ }
表示getLength()
在每次循环迭代时调用。 Java 编译器只允许 移动 getLength()
如果他们可以有效地证明它不会改变可观察到的行为,则调用循环。
(例如,如果 getLength()
只是返回某个变量的值,那么 JIT 编译器有可能内联调用。如果在内联之后,它可以推断出该变量赢了如果不改变(在某些假设下),它可以应用提升优化。另一方面,如果 getLength()
涉及获取并发或同步集合的长度,则允许提升优化的可能性微乎其微。 . 因为其他线程的潜在操作。)
这就是编译器允许做的事情。
I'm wondering if it's possible to activate this kind of feature in the JVM HotSpot?
简单的答案是否定的。
您似乎在建议一个编译器开关,告诉/允许编译器忽略 JLS 规则。没有这样的开关。这样的转换将是一个坏主意。它可能会导致正确/有效/工作程序中断。考虑一下:
class Test {
int count;
int test(String[] arg) {
for (int i = 0; i < getLength(arg); i++) {
// ...
}
return count;
}
int getLength(String[] arg) {
count++;
return arg.length;
}
}
如果允许编译器移动 getLength(arg)
在循环外调用,它会改变调用该方法的次数,因此会改变 test
返回的值方法。
改变正确编写的 Java 程序行为的 Java 优化不是有效的优化。 (请注意,多线程往往会混淆水域。JLS,特别是内存模型规则,允许编译器执行优化,这可能导致不同线程看到应用程序状态的不一致版本......如果它们不同步正确,导致从开发人员的角度来看是不正确的行为。但真正的问题在于应用程序,而不是编译器。)
顺便说一下,您不应该更改循环体中的循环变量的一个更有说服力的理由是它会使您的代码更难理解。
关于java - 用于优化循环语句的 JVM 选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9336704/
我是 PHP 新手。我一直在脚本中使用 for 循环、while 循环、foreach 循环。我想知道 哪个性能更好? 选择循环的标准是什么? 当我们在另一个循环中循环时应该使用哪个? 我一直想知道要
我在高中的编程课上,我的作业是制作一个基本的小计和顶级计算器,但我在一家餐馆工作,所以制作一个只能让你在一种食物中读到。因此,我尝试让它能够接收多种食品并将它们添加到一个价格变量中。抱歉,如果某些代码
这是我正在学习的一本教科书。 var ingredients = ["eggs", "milk", "flour", "sugar", "baking soda", "baking powder",
我正在从字符串中提取数字并将其传递给函数。我想给它加 1,然后返回字符串,同时保留前导零。我可以使用 while 循环来完成此操作,但不能使用 for 循环。 for 循环只是跳过零。 var add
编辑:我已经在程序的输出中进行了编辑。 该程序要求估计给定值 mu。用户给出一个值 mu,同时还提供了四个不等于 1 的不同数字(称为 w、x、y、z)。然后,程序尝试使用 de Jaeger 公式找
我正在编写一个算法,该算法对一个整数数组从末尾到开头执行一个大循环,其中包含一个 if 条件。第一次条件为假时,循环可以终止。 因此,对于 for 循环,如果条件为假,它会继续迭代并进行简单的变量更改
现在我已经习惯了在内存非常有限的情况下进行编程,但我没有答案的一个问题是:哪个内存效率更高;- for(;;) 或 while() ?还是它们可以平等互换?如果有的话,还要对效率问题发表评论! 最佳答
这个问题已经有答案了: How do I compare strings in Java? (23 个回答) 已关闭 8 年前。 我正在尝试创建一个小程序,我可以在其中读取该程序的单词。如果单词有 6
这个问题在这里已经有了答案: python : list index out of range error while iteratively popping elements (12 个答案) 关
我正在尝试向用户请求 4 到 10 之间的整数。如果他们回答超出该范围,它将进入循环。当用户第一次正确输入数字时,它不会中断并继续执行 else 语句。如果用户在 else 语句中正确输入数字,它将正
我尝试创建一个带有嵌套 foreach 循环的列表。第一个循环是循环一些数字,第二个循环是循环日期。我想给一个日期写一个数字。所以还有另一个功能来检查它。但结果是数字多次写入日期。 Out 是这样的:
我想要做的事情是使用循环创建一个数组,然后在另一个类中调用该数组,这不会做,也可能永远不会做。解决这个问题最好的方法是什么?我已经寻找了所有解决方案,但它们无法编译。感谢您的帮助。 import ja
我尝试创建一个带有嵌套 foreach 循环的列表。第一个循环是循环一些数字,第二个循环是循环日期。我想给一个日期写一个数字。所以还有另一个功能来检查它。但结果是数字多次写入日期。 Out 是这样的:
我正在模拟一家快餐店三个多小时。这三个小时分为 18 个间隔,每个间隔 600 秒。每个间隔都会输出有关这 600 秒内发生的情况的统计信息。 我原来的结构是这样的: int i; for (i=0;
这个问题已经有答案了: IE8 for...in enumerator (3 个回答) How do I check if an object has a specific property in J
哪个对性能更好?这可能与其他编程语言不一致,所以如果它们不同,或者如果你能用你对特定语言的知识回答我的问题,请解释。 我将使用 c++ 作为示例,但我想知道它在 java、c 或任何其他主流语言中的工
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我是 C 编程和编写代码的新手,以确定 M 测试用例的质因数分解。如果我一次只扫描一次,该功能本身就可以工作,但是当我尝试执行 M 次时却惨遭失败。 我不知道为什么 scanf() 循环有问题。 in
这个问题已经有答案了: JavaScript by reference vs. by value [duplicate] (4 个回答) 已关闭 3 年前。 我在使用 TSlint 时遇到问题,并且理
我尝试在下面的代码中添加 foreach 或 for 循环,以便为 Charts.js 创建多个数据集。这将允许我在此折线图上创建多条线。 我有一个 PHP 对象,我可以对其进行编码以稍后填充变量,但
我是一名优秀的程序员,十分优秀!