是否有Java编译器或JVM忽略优化语句?
假设我们有下面的陈述是否有Java编译器或JVM忽略优化语句?,java,optimization,Java,Optimization,假设我们有下面的陈述 arrayList.size(); 这句话本身毫无用处。出于优化目的,任何Java编译器或JVM都会忽略此语句吗 实际上,编译器或JVM假定语句没有副作用,因此会将其删除以进行优化 如评论中所述,它并不完全是一个no op:至少,它必须执行空检查。此外,ArrayList的子类可能工作方式不同。理论上,他们甚至可以从数据库或类似的地方获取数据。通常,没有人会为此将ArrayList子类化,但这样的列表实现是有意义的 编译器(JIT,而不是javac)必须能够证明它确实没
arrayList.size();
这句话本身毫无用处。出于优化目的,任何Java编译器或JVM都会忽略此语句吗
实际上,编译器或JVM假定语句没有副作用,因此会将其删除以进行优化 如评论中所述,它并不完全是一个no op:至少,它必须执行空检查。此外,
ArrayList
的子类可能工作方式不同。理论上,他们甚至可以从数据库或类似的地方获取数据。通常,没有人会为此将ArrayList子类化,但这样的列表
实现是有意义的
编译器(JIT,而不是javac)必须能够证明它确实没有副作用。通常情况下,它非常简单
- 它知道是否有任何被重写的
ArrayList.size()
.1实现
- 如果没有,那么它会看到它是一个简单的getter并将其内联
- 这将问题归结为一个无用的字段加载,它将简化为空检查
- 如果以前执行过空检查(例如,由于以前的无用语句:D),也可以消除空检查
- 否则,如果
arrayList
是循环不变量,它可能会移出循环
出于优化目的,任何Java编译器或JVM都会忽略此语句吗
所以我认为这很有可能发生
1这可能会在以后随着此类类的加载而改变,然后将进行去优化。
2假设它决定值得优化。
3如果该方法已经超过内联限制,例如,由于糟糕的编码风格或其他内联,则此操作可能会失败。如注释中所述,它并不完全是无操作:至少,它必须执行空检查。此外,ArrayList
的子类可能工作方式不同。理论上,他们甚至可以从数据库或类似的地方获取数据。通常,没有人会为此将ArrayList子类化,但这样的列表
实现是有意义的
编译器(JIT,而不是javac)必须能够证明它确实没有副作用。通常情况下,它非常简单
- 它知道是否有任何被重写的
ArrayList.size()
.1实现
- 如果没有,那么它会看到它是一个简单的getter并将其内联
- 这将问题归结为一个无用的字段加载,它将简化为空检查
- 如果以前执行过空检查(例如,由于以前的无用语句:D),也可以消除空检查
- 否则,如果
arrayList
是循环不变量,它可能会移出循环
出于优化目的,任何Java编译器或JVM都会忽略此语句吗
所以我认为这很有可能发生
1这可能会在以后随着此类类的加载而改变,然后将进行去优化。
2假设它决定值得优化。
3如果该方法已经超过内联限制,例如,由于糟糕的编码风格或其他内联,则此操作可能失败。可能。为什么不测试它并查看类的字节码呢?Java编译器可能不能;如果arrayList
是某个子类,其size
方法有副作用,该怎么办?愚蠢,是的,但仍然有道理。但是,一些JIT编译器可能会消除它。它真的没有任何作用吗?函数调用可能有副作用。@PlatinumAzure这正是我想知道的。是否有编译器通过假设没有副作用来做出这样的决定。根据代码的上下文,可能无法证明调用没有副作用。编译器不能只是假设,它必须证明它没有副作用。一个副作用(尽管经常被忽略)是,它至少执行空检查。为什么不测试它并查看类的字节码呢?Java编译器可能不能;如果arrayList
是某个子类,其size
方法有副作用,该怎么办?愚蠢,是的,但仍然有道理。但是,一些JIT编译器可能会消除它。它真的没有任何作用吗?函数调用可能有副作用。@PlatinumAzure这正是我想知道的。是否有编译器通过假设没有副作用来做出这样的决定。根据代码的上下文,可能无法证明调用没有副作用。编译器不能只是假设,它必须证明它没有副作用。一个副作用(尽管经常被忽略)是,它至少执行空检查。