Kotlin/Java processBuilder 效率对比 python 子流程
Kotlin/Java processBuilder efficiency vs python subprocesses
我在使用 JVM 进程时遇到问题,我正在尝试创建一个程序,该程序需要多次调用不同的语言程序并更改参数。
例如,假设我需要在 10 秒内通过我的主程序 (KotlinJvm) 调用 node.js 程序 1000 次。
现在,我正在使用 ProcessBuilder class 来创建一个新进程,这样我就可以将信息返回到我的主进程,但速度不够快。它甚至很慢:/
我研究了一下,发现了 python 子进程库,并尝试在那里实现相同的想法。在 python 3.9 中,我的实现效果很好!又快
1.所以我想问,python subprocess 和 Jvm Process
有什么区别
2。有没有办法创建像 python
这样的 Jvm 子进程
据我所知,通过从同一个 ProcessBuilder 调用 .start()
,也可以在 Jvm 中创建子进程,但它仍然很慢。
只是为了确保,如果只调用一次,那不会有问题。
问题是我需要在 10-20 秒内调用此文件 1000 次
在此处添加一些示例代码
Kotlin 示例 - 我测试了一下,waitFor()
函数需要很长时间,这是我的问题
Python 例子
感谢帮助:)
已编辑:
如果是一样的话,有什么办法可以优化Jvm进程的执行吗?任何环境变化?
Python Popen 函数等同于Java ProcessBuilder.start()
方法。
在你上面的例子中,你比较了 Jvm 子进程 complete 和 Python 子进程 start 的时间.
要比较相同的东西,你应该比较:
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 在性能上有显着差异。我会把它放在这里作为测试基础,即使措施没有“正确”完成(通过 Kotlin 的 JMH),它给出了一个想法:
科特林
因此,对于 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
因此,我目前的想法是,一旦执行上下文就绪,两种方法之间的性能应该不会有太大差距。因此,如果您注意到很大的差异,可能是由于子进程之外的某些代码或初始化引起的问题。
在这一点上,需要更多的细节(一个最小的可重现的例子是最好的)来找出正确的答案。
我在使用 JVM 进程时遇到问题,我正在尝试创建一个程序,该程序需要多次调用不同的语言程序并更改参数。
例如,假设我需要在 10 秒内通过我的主程序 (KotlinJvm) 调用 node.js 程序 1000 次。
现在,我正在使用 ProcessBuilder class 来创建一个新进程,这样我就可以将信息返回到我的主进程,但速度不够快。它甚至很慢:/
我研究了一下,发现了 python 子进程库,并尝试在那里实现相同的想法。在 python 3.9 中,我的实现效果很好!又快
1.所以我想问,python subprocess 和 Jvm Process
有什么区别2。有没有办法创建像 python
这样的 Jvm 子进程据我所知,通过从同一个 ProcessBuilder 调用 .start()
,也可以在 Jvm 中创建子进程,但它仍然很慢。
只是为了确保,如果只调用一次,那不会有问题。 问题是我需要在 10-20 秒内调用此文件 1000 次
在此处添加一些示例代码
Kotlin 示例 - 我测试了一下,waitFor()
函数需要很长时间,这是我的问题
Python 例子
感谢帮助:)
已编辑: 如果是一样的话,有什么办法可以优化Jvm进程的执行吗?任何环境变化?
Python Popen 函数等同于Java ProcessBuilder.start()
方法。
在你上面的例子中,你比较了 Jvm 子进程 complete 和 Python 子进程 start 的时间.
要比较相同的东西,你应该比较:
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 在性能上有显着差异。我会把它放在这里作为测试基础,即使措施没有“正确”完成(通过 Kotlin 的 JMH),它给出了一个想法:
科特林
因此,对于 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
因此,我目前的想法是,一旦执行上下文就绪,两种方法之间的性能应该不会有太大差距。因此,如果您注意到很大的差异,可能是由于子进程之外的某些代码或初始化引起的问题。
在这一点上,需要更多的细节(一个最小的可重现的例子是最好的)来找出正确的答案。