不是我第一次遇到这个问题。最大化Java应用程序(香草数据处理)的性能
我通过查看Java Mission Control中的Flight Recorder记录来优化我的Scala/Java代码。查看最热门的方法,然后分配内存,最终应用程序运行速度提高50倍,速度提高3倍。
一旦我达到这一点,CPU使用率为60-90%,而内存使用量例如是2GB的最大4GB堆。但我认为我可以推出更多的速度。
特点:
- 单线程处理,读取来自文件系统中的单个文件。
- 连续读取其中文件系统读取速度为1GB/s,但处理速度低至5MB/s(分支,状态机等)。
- 尽可能减少垃圾收集。
- 没有花哨的库,只是纯粹的JVM代码。
代码看起来大致是这样的(伪代码):
for line in file // using an iterator which would call into a file
result = process_line(line)
state = state.process(result)
if state.emits:
println(state.result)
在一个应用中,我有以下最热的方法:
scala.collection.immutable.HashMap$HashTrieMap.getO(Object, Int, Int) 6.75%
java.io.BufferedInputStream.read() 4.97%
在另一个(这是关闭的。上面有我头):
(some sort of garbage collection process) 9%
... 7%
它仍然值得选择模仿这些?我已经尝试过,并且对于更复杂的代码获得了很少的性能改进。
我应该在哪里看下?
我应该考虑在一个线程上执行process_line()
,然后在另一个线程上迭代状态以最小化上下文切换?也许这就是减慢速度的原因?
这是什么方法?我现在不想并行解决问题。
我会专注于您花费大量时间使用CPU的位置,看看您是否可以优化它或将工作传递给另一个线程。即你正朝着正确的方向前进,你需要继续优化。 –
我更新了问题以包含更多细节。没有“最热”的方法,使用大致相同数量的CPU的不同软件包有一堆。 –
我会怀疑像你有排序的集合,看看你是否可以编写没有它的代码。 BufferedInputStream.read()不应该太昂贵,因为它应该是在理想情况下读取字节的阻塞,但这取决于你为什么这样做。我会看看有多少方法是“噪声”ESP集合操作,而不是你的应用程序的核心逻辑。 –