Kotlin/Java processBuilder效率与python子流程

2024-06-25 22:42:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我在JVM进程方面遇到了问题,我试图创建一个程序,该程序需要调用不同的语言程序,每次都要改变参数,很多次

例如,假设我需要在10秒内通过主程序(KotlinJvm)调用node.js程序1000次

现在,我正在使用ProcessBuilder类来创建一个新的进程,这样我就可以将信息返回到主进程,但速度还不够快。甚至很慢:/

我做了一些研究,了解了python子流程库,并尝试在那里实现同样的想法。在python 3.9中,我的实现非常有效!而且很快

1。所以我想问,python子进程和Jvm进程之间的区别是什么

2。有没有办法创建类似python的Jvm子进程

正如我所读到的,也可以在Jvm中创建子进程,方法是从同一个ProcessBuilder调用.start(),但速度仍然很慢

只是为了确保,如果只打一次电话,这不会是一个问题。 问题是我需要在10-20秒内调用此文件1000次

在这里添加一些代码作为示例

Kotlin示例-我测试了一点,waitFor()函数需要很长时间,这就是我的问题

Kotlin process code

Python示例

Python subprocess code

谢谢你的帮助:)

编辑: 如果这是相同的,是否有任何方法可以优化Jvm进程的执行?环境有变化吗


Tags: 方法程序语言信息node示例参数进程
1条回答
网友
1楼 · 发布于 2024-06-25 22:42:33

PythonPopen函数相当于Java ProcessBuilder.start()方法

在上面的示例中,比较Jvm完成子流程所需的时间与Python启动子流程所需的时间

要比较相同的东西,您应该比较:

Jvm

// Start subprocess
val processHandle = ProcessBuilder("node", "someFile.js").start()
// Wait subprocess to terminate
val returnCode = processHandle.waitFor()

Python

# Start subprocess
val processHandle = subprocess.Popen(["node", "someFile.js")
# Wait subprocess to terminate
val returnCode = processHandle.wait()

编辑

我已经在我的笔记本电脑上运行了这个简单的测试,我并没有看到Kotlin和Python在性能上的显著差异。我将把它放在这里作为测试的基础,即使度量没有“正确地”完成(通过JMH for Kotlin),它给出了一个想法:

科特林

因此,对于Kotlin,我制作了以下.kts脚本:

import java.lang.ProcessBuilder;

fun main() {
    var started : Long = 0
    var completed : Long = 0

    for (i in 0 until 1000) {
        
        val start = System.nanoTime()

        val process = ProcessBuilder("ls").start()
        
        started += (System.nanoTime() - start)
        
        process.waitFor()

        completed += (System.nanoTime() - start)
    }

    println("Average time (ms) to start a process: ${started * 1e-9}")
    println("Average time (ms) to complete a started process: ${completed * 1e-9}")
}

在jre 10上加载到Kotlin REPL 1.4.21后,我得到以下输出:

Average time (ms) to start a process: 0.667509729
Average time (ms) to complete a started process: 5.042644314

Python

在Python 3.7.9上,以下脚本:

import subprocess
from time import perf_counter_ns 

started = 0
completed = 0

for i in range(0, 1000):

    start = perf_counter_ns()

    process = subprocess.Popen("ls")

    started += (perf_counter_ns() - start)
    
    process.wait()

    completed += (perf_counter_ns() - start)

print("Average time (ms) to start a process: ", started * 1e-9)
print("Average time (ms) to complete a process: ", completed * 1e-9)

产出:

Average time (ms) to start a process:  1.620647841
Average time (ms) to complete a process:  6.208644367000001

因此,我目前的想法是,一旦执行上下文就绪,两种方法之间的性能应该不会有太大的差距。因此,如果您注意到很大的差异,那么问题可能是由于子流程之外的一些代码或初始化引起的

在这一点上,需要更多的细节(一个最小的可重复的例子将是最好的)来找到一个正确的答案

相关问题 更多 >