【问题标题】:Java super-tuning, a few questionsJava超调,几个问题
【发布时间】:2011-07-08 19:14:42
【问题描述】:

在我提出问题之前,请不要无缘无故地接受关于优化的讲座。 考虑以下纯学术问题。

我一直在考虑 Java 中根(即经常使用和经常相互访问)类之间的访问效率,但这适用于大多数 OO 语言/编译器。您可以在 Java 中访问某些内容的最快方式(我猜)将是静态最终引用。从理论上讲,由于该引用在加载期间可用,因此一个好的 JIT 编译器将无需进行任何引用查找来访问该变量,并将对该变量的任何访问直接指向一个常量地址。也许出于安全原因,它无论如何都不会那样工作,但请耐心等待......

假设我已经决定在启动时存在一些操作顺序问题或一些参数要传递,这意味着我不能有静态最终引用,即使我要费心让每个类都构造其他建议让 Java 类对彼此具有静态最终引用。我可能不想这样做的另一个原因是……哦,比如说,我正在提供其中一些类的特定于平台的实现。 ;-)

现在我有两个明显的选择。我可以通过静态引用(在某个系统集线器类上)让我的类相互了解,该引用是在构造所有类之后设置的(在此期间我要求它们还不能相互访问,从而消除了操作顺序问题施工期间最少)。另一方面,类可以有 instance 最终相互引用,如果我现在决定整理操作顺序很重要,或者可以由传递参数的人负责 -或者更重要的是,提供我们希望相互引用的这些类的特定于平台的实现。

静态变量意味着您不必在其所属的类中查找变量 wrt 的位置,从而节省了一次操作。 final 变量意味着您根本不必查找该值,但它必须属于您的类,因此您保存“一个操作”。好的,我知道我现在真的在挥手!

然后我想到了其他事情:我可以有静态的最终存根类,有点像一个古怪的接口,其中每个调用都被降级为可以扩展存根的“impl”。那么性能损失将是运行函数所需的双重函数调用,并且可能我猜你不能再声明你的 methods final 了。我假设如果它们被适当地声明,也许它们可以被内联,然后放弃,因为我意识到我将不得不考虑是否可以将'impl's的引用设为静态,或最终,或......

那么这三个中哪一个会最快呢? :-)

关于降低频繁访问开销或什至以其他方式提示 JIT 编译器性能的其他想法?

更新:在对各种事物进行了几个小时的测试并阅读 http://www.ibm.com/developerworks/java/library/j-jtp02225.html 之后,我发现您在调整时通常会看到的大多数事物,例如C++ 使用 JIT 编译器完全消失了。我已经看到它运行了 30 秒的计算一次、两次,并且在第三次(以及随后的)运行中决定“嘿,你没有读取该计算的结果,所以我没有运行它!”。

FWIW,您可以测试数据结构,并且我能够使用微基准测试开发出性能更高的数组列表实现,以满足我的需求。访问模式一定是随机的,足以让编译器猜测,但它仍然解决了如何用我更简单、更优化的代码更好地实现泛型化的增长数组。

就这里的测试而言,我根本无法获得基准测试结果!我对调用函数并从最终与非最终对象引用中读取变量的简单测试揭示了更多关于 JIT 的信息,而不是 JVM 的访问模式。令人难以置信的是,在方法的不同位置调用 same 对象上的 same 函数会改变 FOUR 因子所花费的时间!

正如 IBM 文章中的人所说,测试优化的唯一方法是现场测试。

感谢一路上给我指点的每一个人。

【问题讨论】:

标签: java performance static final initializer


【解决方案1】:

值得注意的是,静态字段存储在一个特殊的每类对象中,该对象包含该类的静态字段。使用静态字段而不是对象字段不太可能更快。

【讨论】:

  • 它可能不会明显更快,但是静态对象不会有一个已知的地址,必须从对象的地址计算对象的字段吗?这是我知道的 C++ 想法,但 JVM/JIT 还能以什么其他有效方式实现它?
  • 它的地址并不比任何其他对象都知道。一个类可以连同它的静态字段一起被加载和卸载。从性能的角度来看,确保您的数据对缓存友好会产生更大的影响。
【解决方案2】:

查看更新,我通过做一些基准测试回答了我自己的问题,发现在意想不到的领域有更大的收益,并且在大多数现代系统上,引用成员等简单操作的性能是相当的,因为内存对性能的限制更多带宽大于 CPU 周期。

【讨论】:

    【解决方案3】:

    假设您找到了一种可靠地分析您的应用程序的方法,请记住,如果您切换到另一个 jdk impl(IBM 到 Sun 到 OpenJDK 等),甚至升级您现有 JVM 的版本,这一切都会消失。

    您遇到问题的原因,并且可能使用不同的 JVM 实现可能会产生不同的结果,在于 Java 规范 - 明确指出它没有定义优化并将其留给每个实现以任何方式优化(或不优化)只要优化没有改变执行行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-30
      • 2015-01-03
      • 2010-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多