当前位置: 首页 > 面试题库 >

JVM选项可优化循环语句

龙俊良
2023-03-14
问题内容

我在学校被告知,修改a的index变量是一种不好的做法for loop

范例:

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()在这种情况下甚至不会调用一次。


问题答案:

我在Java中进行了一些测试,似乎默认情况下每次都会重新计算索引和绑定。

根据Java语言规范,这是:

for(int i = 0 ; i < foo.getLength() ; i++){   }

表示getLength()在每次循环迭代时调用。Java编译器只有在可以有效 证明 它不会改变可观察到的行为的情况下,才 可以
getLength()调用移出循环。 __

(例如,如果getLength()仅返回某个变量的值,那么JIT编译器就有可能内联该调用。如果 内联后
它可以推断出该变量不会改变(在某些假设下),则可以应用提升另一方面,如果getLength()涉及到获取并发或同步集合的长度,则由于其他线程的潜在作用,允许提升优化的机会微乎其微。

这就是 允许 编译器执行的操作。

我想知道是否可以在JVM HotSpot中激活这种功能?

简单回答是不。

您似乎建议使用一个编译器开关,该开关告诉/允许编译器忽略JLS规则。没有这样的开关。这样的开关将是 BAD IDEA
。可能会导致正确/有效/正在运行的程序中断。考虑一下:

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 for循环进行了一些运行时测试,并发现了一种奇怪的行为。对于我的代码,我需要原始类型(例如int,double等)的包装对象来模拟io和输出参数,但这不是重点。只是看我的代码。具有字段访问权限的对象如何比原始类型更快? 优先类型的循环: 结果: MicroTime原语(最大值:= 10000.0):110 MicroTime原语(最大值:= 100000.0):1081

  • 有时候你会遇到循环,或者递归函数,它们会花费很长的执行时间,可能是你的产品的瓶颈。在你尝试使循环变得快一点之前,花几分钟考虑是否有可能把它整个移除掉,有没有一个不同的算法?你可以在计算时做一些其他的事情吗?如果你不能找到一个方法去绕开它,你可以优化这个循环了。这是很简单的,move stuff out。最后,这不仅需要智慧而且需要理解每一种语句和表达式的开销。这里是一些建议: 删除浮点运算操作。

  • 我有一个任务来优化for循环,以便编译器编译运行更快的代码。目标是使代码在 5 秒或更短的时间内运行,原始运行时间约为 23 秒。原始代码如下所示: 我的第一个想法是在内部for循环上进行循环展开,使它降到5.7秒,循环看起来像这样: 在每个循环的阵列中将其取出12个点后,性能不再增加,所以我的下一个想法是尝试引入一些并行性,所以我做了这个: 这实际上最终减慢了代码的速度,并且每个附加变量再次减慢

  • Web 图形格式 Web 图形格式可以是位图(栅格)或矢量。位图格式( GIF、 JPEG、 PNG 和 WBMP)与分辨率有关,这意味着位图图像的尺寸随显示器分辨率的不同而发生变化,图像品质也可能会发生变化。矢量格式( SVG 和 SWF)与分辨率无关,您可以对图像进行放大或缩小,而不会降低图像品质。矢量格式也可以包含栅格数据。可以从 “存储为 Web 和设备所用格式 ”中将图像导出为 SVG

  • 1、什么是循环语句 一般编程语言都有循环语句,为什么呢? 那就问一下自己,我们弄程序是为了干什么? 那肯定是为了方便我们工作,优化我们的工作效率啊。 而计算机和人类不同,计算机不怕苦也不怕累,也不需要休息,可以一直做。 你要知道,计算机最擅长就是做重复的事情。 所以这时候需要用到循环语句,循环语句允许我们执行一个语句或语句组多次。 循环语句的一般形式如下: 在 Python 提供了 for 循环和

  • while 循环:while 条件 do … end repeat 循环:repeat … until 条件 for 循环:for 变量 = 初值,终点值,步进 do … end for 循环:for 变量 1,变量 2,… ,变量 N in表或枚举函数 do … end while 循环 my_table = {1,2,3} local index = 1 -- 注意: table 中的索引从