0

我目前正在开发一个性能是重要考虑因素的系统。它将用于使用非平凡算法(考虑整数编程问题等)处理大量数据(某些对象类型以百万计)。目前我有一个可行的解决方案,可以将所有这些数据点创建为对象。

例如,通过将它们视为数组,是否可以获得任何性能提升?在 Java 中处理大量对象是否有任何最佳实践(应该避免吗?)。

4

4 回答 4

4

我建议您从使用商业 CPU 和内存分析器开始。这将使您很好地了解您的瓶颈是什么。

当您将代码优化到分析器无法提出任何建议的程度时,减少垃圾并让您的内存更紧凑会更有帮助。

您可能想考虑哪些结构更适合您的 CPU 缓存,因为这可以将性能提高多达 2-5 倍。例如,您的 L3 缓存可能是 8 MB,并且比主内存快 5 倍以上。你越能压缩你的工作集以适应它越好。

顺便说一句,您的 L1 缓存是 32 KB 并且再次快了约 10 倍。

这一切都假设执行 GC 的时间不会打扰您。如果您创建了足够多的对象,您可以看到多秒甚至多分钟的 GC 停顿。

于 2013-07-31T16:38:47.547 回答
2

Arrays 或 ArrayLists 具有相似的性能,尽管数组更快(高达 25%,具体取决于您对它们的处理)。您可以通过避免使用盒装原语进行计算来获得显着的性能提升,在这种情况下,唯一的解决方案是使用数组。

除此之外,创建许多短期对象会产生很少的性能成本,除了 GC 会更频繁地运行(但运行 Minor GC 的成本取决于可访问对象的数量,而不是不可访问对象的数量)。

于 2013-07-31T16:40:20.093 回答
2

过早的优化是邪恶的。正如理查德在评论中所说,编写你的代码,看看它是否慢,然后改进它。如果您有疑问,请编写一个示例来模拟高负载。预先花费时间来确定这一点是值得的。

但至于你的问题...

是的,与创建原语相比,创建对象的成本更高。它还占用更多的堆空间(内存)。此外,如果您仅在短时间内使用对象,则垃圾收集器将不得不更频繁地运行,这将消耗一些 CPU。

同样,只有在您确实需要提高速度时才担心这一点。

于 2013-07-31T16:40:26.467 回答
0

对算法的关键部分进行原型设计,分别测试它们,找到最慢的部分,改进,重复。尽可能长时间地保持单线程,但始终记下可以并行执行的操作。

最后,您的瓶颈可能是以下之一:

  • CPU,因为如果算法计算复杂度 => 尝试找到更好的算法(或者如果您略低于目标,则在多个 CPU 上并行运行,如果远低于目标,则并行处理将无济于事)
  • CPU 由于过多的 GC => 配置文件内存,使用低/零 GC 集合(trove4j 等)甚至原始类型数组,甚至来自 NIO 的直接内存缓冲区,实验
  • 内存 - 优化数据接近度(使用匹配缓存大小的分块数组等)。
  • 并发对象的争用 => 恢复为单线程设计,尝试无锁同步原语等。
于 2013-07-31T17:00:09.563 回答