Java HotSpot 枚举开销

7
假设您有一个“简单”的枚举类型:
public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY 
}

然后您在某个地方使用它:

Day day = Day.SUNDAY;
...
if(day==Day.SUNDAY) {...}

这在性能方面与使用整数相比如何(内存和时间)?
int day = Day.SUNDAY;
...
public class Day {
    public static final int SUNDAY=0;
    public static final int MONDAY=1;
}

我们启用了JIT HotSpot编译器以及其他“标准”优化。

你可以比较生成的字节码。 - Victor Sorokin
3
有时候并不完全是关于表现。 - Rohit Jain
可能是 https://dev59.com/t2sz5IYBdhLWcg3wQFUq 的重复问题。 - crownjewel82
@KevinKostlan 对于 Java 进行微秒级别的分析就像试图钉住一个电子。测量本身的行为,包括 JIT 和由其他进程引起的后台噪音,可能会干扰事情,使得测量变得毫无意义。除非您进行了极其严格的基准测试,考虑了 JVM 架构和操作系统调度的不确定性,否则 1 微秒并不具有显著性水平。 - Jim Garrison
1
@Jim Garrison:我曾经有一个“猜测准确”的界面,用于将图像渲染到屏幕上,你可以插入任何函数,并启用HotSpot等功能。当我重新设计它时(没有干扰的代码),每秒帧数显著提高了。因此,这种性能损失具有实际应用。我的函数相当昂贵(100纳秒左右),所以令人惊讶的是,界面开销成为了瓶颈,对性能产生了真正的影响。 - Kevin Kostlan
显示剩余3条评论
1个回答

7

每当您引用 Day.SUNDAY 时,枚举可能会稍微降低性能,因为 int 常量是编译时常量,因此可以进行内联,而枚举常量需要 getstatic。

当然,比较两个 int 或两个引用在所需的时间方面是相同的,因为您正在比较引用(地址),而不是调用 .equals()。

当然,这里的性能损失微不足道;担心这一点的唯一原因是如果这在您的应用程序的性能关键部分中,并且分析显示使用 int 更好。枚举对于可维护性和代码正确性的好处远远超过像这样轻微的效率问题。


整数不是原始类型吗?因此值被比较,尽管两者都非常便宜?在1000个Hotspot使用标准之后,getstatic不会被内联吗? - Kevin Kostlan
@Kevin Kostlan:getstatic是一个静态字段访问,它是一个原子操作(读取某个内存位置)。没有什么可以内联的。由于枚举常量的static字段是final的,JVM可能会将对同一字段的多个访问合并为一个,但始终会保留一个访问。然而,JIT优化的工作方式相反:提供您要比较的两个值的代码可能会被内联、分析和简化,直到JVM可以从剩余的代码中推断出比较结果。然后可以完全删除比较。 - Holger
好的,现在我感觉很幼稚。不管怎样,这很便宜。 - Kevin Kostlan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接