Py4J 的开销比 Jython 和 JPype 大
Posted
技术标签:
【中文标题】Py4J 的开销比 Jython 和 JPype 大【英文标题】:Py4J has bigger overhead than Jython and JPype 【发布时间】:2013-08-31 08:21:31 【问题描述】:在搜索从 Django 应用程序(python)运行 Java 代码的选项后,我发现 Py4J 是我的最佳选择。我试过 Jython、JPype 和 Python 子进程,它们都有一定的局限性:
Jython。我的应用在 python 中运行。 JPype 有问题。您可以只启动一次JVM,然后它无法再次启动。 Python 子进程。由于常规控制台调用,无法在 Python 和 Java 之间传递 Java 对象。Py4J网站上写着:
在性能方面,Py4J 的开销比之前的两种解决方案(Jython 和 JPype)都要大,因为它依赖于套接字,但如果性能对您的应用程序至关重要,那么从 Python 程序访问 Java 对象可能不是最好的想法。
在我的应用程序中,性能至关重要,因为我正在使用机器学习框架 Mahout。我的问题是:Mahout 是否也会因为 Py4J 网关服务器而运行更慢,或者这种开销只是意味着从 Python 函数调用 Java 方法更慢(在后一种情况下,Mahout 的性能不会成为问题,我可以使用 Py4J)。
【问题讨论】:
真的需要多次启动JVM吗?为什么? 【参考方案1】:我不认识 Mahout。但请想一想:至少使用 JPype 和 Py4J 在将类型从 Java 转换为 Python 时会产生性能影响,反之亦然。尽量减少语言之间的调用。也许你可以用 Java 编写一个瘦包装器,将许多 Java 调用压缩为一个 python2java 调用。
【讨论】:
【参考方案2】:因为性能也是一个关于您的使用场景的问题(您调用脚本的频率以及移动的数据有多大)并且因为不同的解决方案有其特定的优点/缺点,所以我创建了一个 API 来无需更改 python 脚本即可在不同的实现之间切换:https://github.com/subes/invesdwin-context-python
因此,测试什么效果最好,或者只是灵活地部署到什么,真的很容易。
【讨论】:
【参考方案3】:PySpark 非常成功地使用了 Py4J。如果所有繁重的工作都是在 Spark(或您的情况下的 Mahout)本身上完成的,并且您只想将结果返回给“驱动程序”/Python 代码,那么 Py4J 也可能非常适合您。
Py4j 对巨大结果的开销稍大一些(Spark 工作负载不一定是这种情况,因为您只返回数据帧的摘要/聚合)。有一个关于 py4j 切换到二进制序列化的改进讨论,以消除更高的 badnwidth 要求的开销:https://github.com/bartdag/py4j/issues/159
【讨论】:
【参考方案4】:@HIP_HOP 提到的 JVM 与新线程分离的 JPype 问题可以通过以下 hack 解决(在还没有 JVM 的新线程中第一次调用 Java 对象之前添加它):
# ensure that current thread is attached to JVM
# (essential to prevent JVM / entire container crashes
# due to "JPJavaEnv::FindClass" errors)
if not jpype.isThreadAttachedToJVM():
jpype.attachThreadToJVM()
【讨论】:
以上是关于Py4J 的开销比 Jython 和 JPype 大的主要内容,如果未能解决你的问题,请参考以下文章
Jython 或 python 2.7 比传统字符串连接更好的字符串连接方法
尽管 JVM 取得了进步,为啥 Jython 比 CPython 慢得多?