Kotlin/Java processBuilder效率与python子流程
我在JVM进程方面遇到了问题,我试图创建一个程序,该程序需要调用不同的语言程序,每次都要改变参数,很多次 例如,假设我需要在10秒内通过主程序(KotlinJvm)调用node.js程序1000次 现在,我正在使用ProcessBuilder类来创建一个新的进程,这样我就可以将信息返回到主进程,但速度还不够快。它甚至很慢:/ 我做了一些研究,了解了python子流程库,并尝试在那里实现同样的想法。在python 3.9中,我的实现非常有效!而且很快 1。所以我想问,python子进程和Jvm进程之间的区别是什么 2。有没有办法创建类似python的Jvm子进程 正如我所读到的,通过从同一个ProcessBuilder调用Kotlin/Java processBuilder效率与python子流程,java,python,kotlin,process,subprocess,Java,Python,Kotlin,Process,Subprocess,我在JVM进程方面遇到了问题,我试图创建一个程序,该程序需要调用不同的语言程序,每次都要改变参数,很多次 例如,假设我需要在10秒内通过主程序(KotlinJvm)调用node.js程序1000次 现在,我正在使用ProcessBuilder类来创建一个新的进程,这样我就可以将信息返回到主进程,但速度还不够快。它甚至很慢:/ 我做了一些研究,了解了python子流程库,并尝试在那里实现同样的想法。在python 3.9中,我的实现非常有效!而且很快 1。所以我想问,python子进程和Jvm进程
.start()
,也可以在Jvm中创建子进程,但速度仍然很慢
只是为了确保,如果只打一次电话,这不会是一个问题。
问题是我需要在10-20秒内调用此文件1000次
在这里添加一些代码作为示例
Kotlin示例-我测试了一点,waitFor()
函数需要很长时间,这就是我的问题
Python示例
谢谢你的帮助:)
编辑:
如果这是相同的,是否有任何方法可以优化Jvm进程的执行?任何环境变化?Python Popen函数相当于Java
ProcessBuilder.start()
方法
在上面的示例中,比较Jvm完成子流程所需的时间与Python启动子流程所需的时间
要比较相同的东西,您应该比较:
虚拟机
到
python
#启动子流程
val processHandle=subprocess.Popen([“node”,“someFile.js”)
#等待子进程终止
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上,以下脚本:
导入子流程
从时间导入性能计数器
开始=0
已完成=0
对于范围(0,1000)内的i:
开始=性能计数器()
进程=子进程.Popen(“ls”)
已启动+=(性能计数器()-启动)
process.wait()
已完成+=(性能计数器()-开始)
打印(“启动流程的平均时间(ms):,已启动*1e-9)
打印(“完成流程的平均时间(毫秒):,已完成*1e-9)
产出:
Average time (ms) to start a process: 1.620647841
Average time (ms) to complete a process: 6.208644367000001
因此,我目前的想法是,一旦执行上下文就绪,两种方法之间的性能应该不会有太大的差距。因此,如果您注意到很大的差异,那么问题可能是由于子流程之外的一些代码或初始化引起的
在这一点上,需要更多的细节(一个最小的可重复的示例最好)来找到正确的答案。Python Popen函数相当于Java
ProcessBuilder.start()
方法
在上面的示例中,比较Jvm完成子流程所需的时间与Python启动子流程所需的时间
要比较相同的东西,您应该比较:
虚拟机
到
python
#启动子流程
val processHandle=subprocess.Popen([“node”,“someFile.js”)
#等待子进程终止
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上,以下脚本:
导入子流程
从时间导入性能计数器
开始=0
已完成=0
对于范围(0,1000)内的i:
开始=性能计数器()
进程=子进程.Popen(“ls”)
已启动+=(性能计数器()-启动)
process.wait()
已完成+=(性能计数器()-开始)
打印(“启动流程的平均时间(ms):,已启动*1e-9)
打印(“完成流程的平均时间(毫秒):,已完成*1e-9)
产出:
Average time (ms) to start a process: 1.620647841
Average time (ms) to complete a process: 6.208644367000001
因此,我目前的想法是,一旦执行上下文就绪,两种方法之间的性能应该不会有太大的差距。因此,如果您注意到很大的差异,那么问题可能是由于子流程之外的一些代码或初始化引起的
在这一点上,更多的细节(一个最小的可重复的例子将是最好的)需要找到正确的答案。好的,我知道我需要添加等待python。尝试了之后,python仍然比Jvm快得多。有什么想法吗?好吧,这真是个谜…我试过运行与您运行的代码相同的代码。毫无疑问,您的笔记本电脑比我的要好:D我的python程序运行了9秒,但kotlin运行了26秒…我检查一下在我的kotlin版本和jdk中,唯一的区别是我使用openJdkI的jdk 15得到了与你类似的结果,但程序本身并没有解释这一点。如果我在脚本模式下启动kotlin示例,它需要的时间是Python的2倍(约13秒vs约6秒)但是,当预编译时,时间会下降到约5秒,类似于Python。额外的时间不是由程序本身花费的,而是由初始化应用程序上下文(编译、JIT、Gc等)所需的Kotlin/Java大型机器造成的巨大开销。它们在该doma中的性能非常差