【问题标题】:does a Java getter incur a performance penaltyJava getter 是否会导致性能损失
【发布时间】:2010-04-06 04:39:05
【问题描述】:

如果我有代码

int getA(){
 return a;
}

然后做类似的事情

int b = obj.getA();

而不是

int b = obj.a;

这是否意味着必须推送和弹出堆栈最终会减慢我的代码速度?

【问题讨论】:

  • 性能问题是无用的。在确定它在您的应用程序中的性能敏感条带中后,您自己对其进行分析。

标签: java


【解决方案1】:

JIT 编译器将内联该方法。

代码应该是这样的

int b = obj.GetA();

【讨论】:

  • 这不正确。 C/C++ 编译器会内联这种函数,但在 Java 中你不能,因为 VM 不知道函数是否会被引用(使用 AOP、AspectJ 等)。
  • @cletus 虚拟机解释所有 Java 字节码指令,因此,它知道这一点 - 甚至是像 AspectJ 这样的字节码编织工具所做的修改
  • @binil, Michael:除非 getter 是最终的,否则这将如何工作?覆盖 getter 的子类呢?
  • @cletus,现代 JVM 显然可以检测到该方法在使用它的实际位置没有被覆盖并内联。如果这种情况发生变化,有问题的代码会返回解释,然后可能会再次优化。
【解决方案2】:

我有两个答案:

  1. 我认为使用 getter 与直接访问变量相比,不会有显着的性能损失。我更担心代码的可理解性和可读性,而不是此类决定的性能。
  2. 根据 OO 设计原则,这可能对您来说很重要,也可能不重要,您通常会隐藏数据并提供 getter 方法来访问它 — 有关此方法的优点的详细讨论 here

【讨论】:

  • 另一方面,get 方法通常会破坏封装(尤其是在伴随set 方法的情况下)。
【解决方案3】:

理论上,由于进行了方法调用,因此存在一些运行时损失。实际上,这对整体性能影响很小,原因有两个:

  1. 除非obj.getA() 发生在程序的最内层循环中,否则它对代码整体性能的影响可以忽略不计。当性能成为问题时,您应该考虑代码的瓶颈。优化不在这些热点的代码是没有意义的。为了识别这些点,您需要通过profiler 分析代码的执行情况。
  2. 正如@Michael 所说,JVM 使用“及时”编译器/优化器,根据实际执行情况内联代码。它只执行这种优化(参见talk

【讨论】:

    猜你喜欢
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 2018-04-23
    • 1970-01-01
    • 2020-04-02
    相关资源
    最近更新 更多