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

为什么HotSpot将使用提升来优化以下内容?

祁飞飙
2023-03-14
问题内容

在“有效的Java”中,作者提到

while (!done) i++;

可以通过HotSpot优化为

if (!done) {
    while (true) i++;
}

我对此很困惑。变量done通常不是 const ,为什么编译器可以这样优化?


问题答案:

作者在那里假设该变量done是局部变量,在Java内存模型中,它不需要任何条件即可将其值公开给其他没有同步原语的线程。或用另一种方式说:done除此处显示的内容外,任何其他代码都不会更改或查看w
的值。

在这种情况下,由于循环不会更改的值done,因此可以有效地忽略其值,并且编译器可以在循环外提升对该变量的求值,从而防止其在循环的“热门”部分中求值。
。这使循环运行得更快,因为它要做的工作更少。

这也适用于更复杂的表达式,例如数组的长度:

int[] array = new int[10000];
for (int i = 0; i < array.length; ++i) {
    array[i] = Random.nextInt();
}

在这种情况下,朴素的实现将评估数组的长度10,000次,但是由于从未分配变量数组,并且数组的长度也不会改变,因此评估可以更改为:

int[] array = new int[10000];
for (int i = 0, $l = array.length; i < $l; ++i) {
    array[i] = Random.nextInt();
}

其他优化也适用于与提升无关的优化。

希望能有所帮助。



 类似资料:
  • 问题内容: 为什么JavaScript会提升变量? 设计师决定实施吊装时的基本原理是什么?还有其他流行的语言可以做到这一点吗? 请提供文档和/或记录的相关链接。 问题答案: 正如Stoyan Stefanov在“ JavaScript模式”一书中解释的那样,提升是JavaScript解释器实现的结果。 JS代码解释分两次进行。在第一遍中,解释器处理变量和函数声明。 第二遍是实际的代码执行步骤。解释

  • 根据我的理解,虚拟DOM是一个由Javascript对象组成的树,有父/子对象等,但没有真正DOM的大部分“沉重”特性。框架(例如React/VUE)通过从头创建一个虚拟DOM来响应模型状态的变化,然后对虚拟DOM的最后一个版本进行比较,以确定要改变什么真实的DOM。 我读过的许多文章都声称虚拟DOM的速度更快,因为真正的DOM在每次发生更改时都必须重新布局(甚至重新绘制),但事实并非如此--只有

  • 本文向大家介绍canvas有哪些可以提升性能的优化方法?相关面试题,主要包含被问及canvas有哪些可以提升性能的优化方法?时的应答技巧和注意事项,需要的朋友参考一下 一般画下一帧会 clearRect,但当本帧绘制情况很复杂,会造成一定的白屏或黑屏, 所以会有一个临时 canvas 保留上一帧,因为直接 draw 不怎么消耗计算资源, 在发现绘制未完成时,用临时 canvas 显示。 在 ios

  • 我正在阅读每个程序员都应该知道的内存https://people.freebsd.org/~lstewart/articles/cpumemory.pdf,它说内联函数使你的代码更可优化 例如 :特别是函数的内联允许编译器一次优化更大的代码块,这反过来又可以生成机器代码,从而更好地利用处理器的管道架构。 and: 当程序的较大部分可以被视为单个单元时,代码和数据的处理(通过死代码消除或值范围传播等

  • 问题内容: 纯方法是没有副作用的方法:它们的唯一作用是返回一个值,该值是其参数的函数。 使用相同的参数两次调用相同的纯方法将返回相同的值。因此,给定两次对具有相同参数的纯方法的调用,HotSpot是否可以简单地重用第一次调用中的值来优化第二次调用? 例如: 如果热点不在线内它理解为 纯粹的 ,因此呼吁只有一次,双倍返还价值? 当然,这种琐碎的[mcve]不太可能引起人们的直接关注,但是实际上,由于

  • 如果类型具有类内存,则调用方为返回值提供空间,并将此存储的地址传递到%RDI中,就像它是函数的第一个参数一样。实际上,这个地址成为一个“隐藏”的第一个参数。此存储区不得通过此参数以外的其他名称与被调用方可见的任何数据重叠。 返回时,%RAX将包含调用方在%RDI中传入的地址。 考虑到这一点,下面的(愚蠢的)函数: 不用说,对于SSE类的类型(例如,只有2个和不是3个doubles),会执行尾调优化