【问题标题】:Java HotSpot Enum overheadJava HotSpot 枚举开销
【发布时间】:2014-01-16 16:31:04
【问题描述】:

假设你有一个“简单”的枚举:

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 编译器以及其他“标准”优化。

【问题讨论】:

  • 您可以比较生成的字节码。
  • 有时这与性能无关。
  • 这个问题主要是学术性的。但是,最近我遇到了 1000 ns 左右的接口调用开销;当我删除灵活的基于接口的代码时,性能显着提高。那是巨大的!可能接口调用的函数不能内联?
  • @Jim garrison:我有一个“可靠的猜测”界面,用于将图像渲染到屏幕上,您可以在其中插入任何功能,启用 HotSpot 等。当我重新做时没有干扰(较少可维护的代码),它以每秒帧数显着加快。因此,这种性能冲击具有实际应用。我的函数相当昂贵(100 ns),所以令人惊讶的是接口开销是一个真正影响的瓶颈。

标签: java performance enums


【解决方案1】:

每当您引用 Day.SUNDAY 时,枚举的性能可能会略有下降,因为 int 常量是编译时常量,因此可以内联,而 enum 常量需要 getstatic

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

当然,这里的性能影响微乎其微;担心这一点的唯一原因是,如果这是在应用程序的性能关键部分,并且分析表明使用 int 更好。枚举在可维护性和代码正确性方面的好处远远超过了这种轻微的低效率。

【讨论】:

  • 不是 ints 原语,所以比较价值,虽然两者都很便宜?在 1000 个左右的热点使用标准之后不会内联 getstatic 吗?
  • @Kevin Kostlan:getstatic 是一个静态字段访问,它是一种原子操作(读取某个内存位置)。没有什么可以内联的。由于enum 常量的static 字段是final,JVM 可能会将对同一字段的多个访问合并为一个,但始终会保留一个访问。但是,JIT 优化以另一种方式工作:提供您正在比较的两个值的代码可能会被内联、分析和简化,直到 JVM 可以从剩余代码中推断出比较的结果。然后可以完全删除比较。
  • 好吧,现在我觉得很幼稚。无论哪种方式,它都很便宜。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-25
相关资源
最近更新 更多