【问题标题】:Optimization Strategies around Interface Calls in JavaJava中围绕接口调用的优化策略
【发布时间】:2011-07-24 00:47:40
【问题描述】:

我有一个使用提供者模式的应用程序。应用程序通过调用应用程序定义的接口来利用提供程序实现。

我目前正在研究如何围绕接口调用优化我的应用程序。

我可以将我的应用程序的复杂性限制在以下范围内:

  1. 我只需要在启动时动态加载一次实现
  2. 我在任何时候都只需要一个提供程序实现,用于应用程序实例的一组特定接口。

我很感激人们付诸实践的任何策略:

  1. 减少接口调用
  2. 一般直接调用接口实现类的任何技巧。
  3. 各种方法可以更好地利用任何编译器优化。

谢谢!

【问题讨论】:

  • 我首先要引用 Donald Knuth:“过早的优化是万恶之源”。现在的问题。你真的需要这样的优化吗?我正在研究接口调用如何在不同的 JVM 中工作(这是我文凭的一部分),我可以说通常没有必要优化/减少它们。所以如果你想优化你的应用,首先要找到真正的瓶颈。
  • 我同意 xappymah。他必须运行什么样的应用程序才能调用方法的开销导致明显的性能损失?!
  • 我同意关于过早优化的说明。我的标准做法是用简洁的设计构建一些东西,然后优先优化瓶颈,在常量之前关注算法。我实际上正在考虑构建一个事务性内容存储引擎(所以称它为应用程序并不是很准确)。有一个类似的系统是用 C 实现的。这个问题实际上是我正在思考的更大问题的一部分:我是否应该用 C 或 C++ 而不是 Java 来实现它。

标签: java performance optimization interface design-patterns


【解决方案1】:

一些值得在这里解决的误解。

  1. 您可以通过直接调用底层的具体实现(或使用抽象类)来减少接口调用 当它简化设计并提高可维护性时应该这样做(通常 更多 接口会有所帮助,但不总是)

  2. 您可以将接口引用转换为具体引用并使用它。这通常是不好的编程习惯,对性能影响不大。通常,只有在正确重构的工作量大于其价值时,您才会这样做。 (这不是一种好的设计方法,但可以是一种实用的方法)

  3. 编译器不会以任何重要的方式优化代码。它所做的一些优化(例如内联编译时间常量)你可能不需要。 JVM 在运行时进行有用的优化。第二次猜测 JVM 会做什么并尝试优化您的代码是一个跟踪和错误过程。如果您尝试 10 件您认为应该有所帮助的事情,其中​​ 1 件会显着加快速度,6 件几乎没有区别,3 件会使其变慢。即简单的代码往往会得到最好的优化。

与 C++ 不同,大多数 JVM 可以优化虚函数的开销,尤其是在实际使用的只有一两个实现的情况下。即它可以根据代码的使用方式而不是编译器可以静态确定的内容来优化代码。

【讨论】:

  • 是的,hotspot 大量尝试推理它是否可以取代虚拟调用,所以如果你只有一个接口的实现,它肯定会优化它。如果你有不同的实现,它会变得更复杂。
  • 谢谢,这很有帮助。我不知道大多数 JVM 在实现很少时会优化虚函数的成本。
  • 它甚至可以内联最多两个使用频率很高的方法,如果不是这两个方法之一,它仍然可以调用另一个虚拟方法。 ;)
【解决方案2】:

听起来你做错了。

  1. 精心设计的界面可以减少而不是增加应用程序的复杂性。通常与提供者一起使用的接口应该有助于划分系统。如果您觉得直接访问实现会更简单,那么您的接口可能需要重新设计。

  2. “接口调用”的运行时开销是如此微不足道,以至于您不太可能遇到它在工作系统和非工作系统之间产生差异的情况。

    李>
  3. 一般来说,Java 编译器本身做的优化很少。它的大部分发生在运行时,因此您的代码越“自然”,JIT 编译器就会越好地处理它。如果您尝试使用技巧来强制进行这种或那种优化(例如手动内联代码或重用变量),您最终可能会得到较慢的代码。

总结一下;如果您想降低应用程序的复杂性,请确保您的模块在应有的位置分开(您拥有的模块间依赖项越少越好)并使用代码分析器工具来跟踪复杂性指标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多