python - python中用于解释的子进程效率
问题描述
我在这里询问python子进程的效率。
我正在尝试创建一个需要能够执行其他语言代码的程序。例如,假设我需要运行 js 文件(所以我会使用节点解释器)
我正在使用一个简单的代码(基于我之前提出的关于 Kotlin ProcessBuilder 与 python 的问题),而且我不明白为什么使用命令行调用py
和调用cmd
会使时间差差 10 倍
import subprocess
from time import perf_counter_ns
started = 0
completed = 0
def call():
process = subprocess.Popen(["node", "printHello.js"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
process.wait()
for i in range(0, 1000):
if (i % 20 == 0):
print("Turn ", i)
start = perf_counter_ns()
call()
started += (perf_counter_ns() - start)
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)
打印结果(没有烦人的“转:xxx”)
启动进程的平均时间(毫秒):47.2123976
完成一个过程的平均时间(毫秒):47.2141487
代码 2
import subprocess
from time import perf_counter_ns
started = 0
completed = 0
def call():
process = subprocess.Popen(["cmd", "/c", "dir"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
process.wait()
for i in range(0, 1000):
if (i % 20 == 0):
print("Turn ", i)
start = perf_counter_ns()
call()
started += (perf_counter_ns() - start)
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)
打印结果(没有烦人的“转:xxx”)
启动进程的平均时间(毫秒):5.566161500000001
完成一个过程的平均时间(毫秒):5.5675167000000005
现在,这是一个很大的区别,我知道这些不是相同的命令,1 使用 os 和一个正在解释,但为什么解释这么慢?有谁知道为什么它这么慢,有没有办法让它更快?我已经搜索并发现了 pypy,它应该可以加速性能,但它并没有达到我想要的效果。我知道这可以使它更快(或者至少是使用 Python 2.7),因为我曾经使用过这样做的脚本。没有编写该脚本的代码,所以我不知道它为什么在那里工作,我发现的唯一线索是它使用了 psyco。
所以我的问题是:
- Python 不应该用命令
console.log("hello")
比我取得的结果更快地调用节点解释器吗?(我的电脑很好,不是那个) - 无论如何通过节点或java(使用子进程或任何其他模块)等子进程来提高调用解释器/编译器的性能
谢谢 :)
解决方案
因此,经过更多研究,我发现了为什么我看到的代码运行良好而我的代码却没有。
正如 Charles Duffy 所说,打开许多子流程很繁重。代码中的解决方案是使用一个线程来启动 1 个子进程,它只会接收许多输入,而不是多次调用同一个子进程。傻我...愚蠢的简单,谢谢你的帮助!
推荐阅读
- php - Laravel:使用 store() 上传时更改文件名
- unit-testing - 将 .NET Core XUnit 项目的代码覆盖率添加到 VSTS 构建
- typescript - 使用 Typescript 2.8 React Native - 无法重新声明块范围变量“控制台”
- scala - 如何使用 scala 将 csv 字符串解析为 Spark 数据帧?
- go - 了解从频道读取的行为
- c# - Visual C#,两个日期之间的日期数组
- android - 无法通过广播从服务到片段获取数据
- laravel - Laravel 配置
- c++ - 在 G++ 中编译时出现 C++ 多定义错误
- python - 通过偏序集的方式数