7

在搜索从 Django 应用程序(python)运行 Java 代码的选项后,我发现 Py4J 是我的最佳选择。我尝试了 Jython、JPype 和 Python 子进程,它们中的每一个都有一定的限制:

  • 杰通。我的应用程序在 python 中运行。
  • JPype 有问题。您可以只启动一次 JVM,然后它无法再次启动。
  • Python 子进程。由于常规控制台调用,无法在 Python 和 Java 之间传递 Java 对象。

在 Py4J 网站上写着:

在性能方面,Py4J 的开销比之前的两种解决方案(Jython 和 JPype)都要大,因为它依赖于套接字,但如果性能对您的应用程序至关重要,那么从 Python 程序访问 Java 对象可能不是最好的主意。

在我的应用程序中,性能至关重要,因为我正在使用机器学习框架 Mahout。我的问题是:Mahout 是否也会因为 Py4J 网关服务器而运行得更慢,或者这种开销只是意味着从 Python 函数调用 Java 方法更慢(在后一种情况下,Mahout 的性能不会成为问题,我可以使用 Py4J)。

4

4 回答 4

1

我不认识马豪。但请想一想:至少使用 JPype 和 Py4J 在将类型从 Java 转换为 Python 时会对性能产生影响,反之亦然。尽量减少语言之间的调用。也许它是您在 Java 中编写一个瘦包装器的另一种选择,它将许多 Java 调用压缩为一个 python2java 调用。

于 2014-01-13T18:26:42.290 回答
1

因为性能也是一个关于您的使用场景的问题(您调用脚本的频率以及移动的数据有多大)并且因为不同的解决方案有其特定的优点/缺点,所以我创建了一个 API 来在不同的无需更改 python 脚本即可实现:https ://github.com/subes/invesdwin-context-python

因此,测试什么效果最好或者只是灵活地部署到什么是非常容易的。

于 2017-06-09T10:27:08.933 回答
1

@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()
于 2019-05-09T04:58:32.810 回答
1

PySpark 非常成功地使用了 Py4J。如果所有繁重的工作都是在 Spark(或您的情况下的 Mahout)本身上完成的,并且您只想将结果返回给“驱动程序”/Python 代码,那么 Py4J 也可能对您非常有用。

Py4j 对于巨大的结果有稍大的开销(Spark 工作负载不一定是这种情况,因为您只返回数据帧的摘要/聚合)。有一个关于 py4j 切换到二进制序列化以消除更高 badnwidth 要求的开销的改进讨论:https ://github.com/bartdag/py4j/issues/159

于 2016-04-24T16:45:47.440 回答