我试图在一些大 CSV 文件的每一行上运行一些自定义逻辑,大约 10 GB数据。
尝试过 python 数据帧、python 中的多处理、pyspark。他们都没有在可接受的时间内完成。
然后我发现了java流。我有一个使用 pyspark 需要 70 分钟的工作流程。使用 Java 流需要 3.5 分钟。
更多人应该了解流。
流操作比我尝试过的任何操作都更直观。多亏了流,我可以在创纪录的时间内对我们的数据进行大量分析。
网友分析:
1、Java 可能只比 Python 快 10 倍。与流本身无关。
2、Python 可以是高性能的——前提是你实际上没有将 python 用于任何事情。这意味着使用委托给 C/C++(最近可能还有 Rust)的库,并且要小心不要在 python 中实际进行任何密集计算。
要做到这一点通常并不容易,而且像 PySpark(以及以上述方式使用它)这样的东西的学习曲线要高得多,而且更难维护。但这并不意味着 Python 不能用于高性能应用程序。
3、在 Java 中会更容易、性能更高。(也更少的语言,这总是一个加号)。
这是因为 JVM 在“预热”代码点(因此得名 jvm 热点)中进行的运行时优化。
C/C++ 优化的区别在于它们运行的时间。编译时间与运行时间。在运行时,JVM 有一些优势,因为有更多关于如何优化和优化什么的信息可用。
Java 代码可以达到一些荒谬的速度......最好的部分是,与 C 相比,它也非常容易编写。
唯一的缺点是所谓的“冷启动”。在热点优化器启动之前,它基本上表现得比其他任何东西都差。但在像你这样的情况下,它应该启动得非常快,甚至可能在第一个循环之后。
3、虽然我喜欢流,但除非您使用并行流,否则流 API 应该不会对性能产生影响。只需添加“.parallel()”即可。
4、并行流Parallel 将获取您的流并通过内部线程池运行每次迭代,从而提高性能。但请注意:
- 该线程池在整个应用程序中共享。如果您有多个并行流(或依赖此池的其他操作),性能将会下降。
- 流方法中的每个操作(即传递给 map、filter 等的函数)都需要是线程安全的。这绝对意味着 100% 没有共享的变异状态。如果你不知道我在说什么,那么在继续使用并行流之前,你需要更多地了解如何安全地使用线程。
当你用Java写一个普通集合遍历:
for (Data datum : someCollection) { |
循环中的小块处理不能轻易地通过 JIT实现,但是你改写为流:
someCollection().stream() |
这些函数中的每一个都在 Java 中被编译为一个单独的函数,并且 JIT 可以轻松地优化小函数。
您处理数据的方式,将流的每个部分都作为一个小函数,使 Java 更容易优化小部分,并在处理数据时获得相当大的性能提升。
流中的函数还有其他一些无法完成的副作用,因此可以进行更积极的优化。
试过tablesaw图书馆吗?它是 Java 中的数据帧,具有流支持。https://jtablesaw.github.io/tablesaw/