Python和C 程序与子过程之间的沟通非常缓慢
Very slow communication between Python and C++ program with subprocess
我试图通过使用子过程Python模块将一些重复计算外包给C 程序来加快Python程序。
为了说明我的问题,我采用了一个简单的C 代码,该代码返回输入的双重。一百万个整数需要16秒,这似乎很慢。
这是C 程序(double.exe):
#include <iostream>
using namespace std;
int main()
{
int a;
bool goon = true;
while (goon)
{
cin >> a;
cout << 2 * a << endl;
if (a == 0)
goon= false;
}
}
和这里的python 3代码:
from time import time
from subprocess import PIPE,Popen
cmd = ["double"]
process = Popen(cmd, stdin=PIPE,stdout=PIPE, bufsize=32,universal_newlines=True, shell=True)
t0 = time()
for i in range(1,int(1e6)):
print(i, file=process.stdin, flush=True)
output = int(process.stdout.readline())
dt = time() - t0
print("Time to communicate : %fs" % dt)
print(0,file=process.stdin,flush=True) # close 'double' program
交流的时间:16.029137S
对我来说,它如此慢的原因只能是Python过程与C 程序之间的通信,但是我没有找到如何加速它。使用子过程或其他库的任何解决方案可以加快此通信?
我在Windows上使用Python 3.5.2。
问题本身不是stdin通信,而是大规模上下文切换。您在C 代码中执行一个很小的"任务",但是对于每个此类任务,Python代码都应将数据写入管道,冲洗,睡觉,C 零件醒来,醒来,解析输入,计算结果,打印结果,打印出来。输出,冲洗并入睡。然后,Python代码醒来等等
睡觉并醒来(以及关联的上下文切换)不是免费的。随着"任务"的大小(将输入乘以两个),这大多数时候都会消耗。
您可以通过分批向C 程序提供工作或更大的任务来"修复"该工作。或两者。
例如,具有数百万个数字的同一工作,但是如果每次写入后管道冲洗,则使用10个数字的批次运行速度快2倍。代码:
for i in range(1,int(1e5)):
for j in range(1, 10):
print(i*10 + j, file=process.stdin, flush=True)
for j in range(1, 10):
output = int(process.stdout.readline())
如果每10个数字仅完成一次冲洗,则其运行速度比上一个示例快1.5倍(或原始代码快3倍):
for i in range(1,int(1e5)):
for j in range(1, 10):
print(i*10 + j, file=process.stdin)
process.stdin.flush()
for j in range(1, 10):
output = int(process.stdout.readline())
如果"任务"更大,那么您必须为上下文开关支付的价格相同。但是,与任务的大小相比,这并不大。例如,让我们想象上下文开关需要0.1秒(在现实生活中它越小,这只是一个例子)。如果任务是在1毫秒中完成的乘法(例如,仅仅是),则与任务相比,上下文开关开销为10000%。但是,如果您的任务很重,并且需要1次执行,则开销仅为10%。相对值的1000倍。
只是一个猜测,但这可能是由于std :: endl不仅编写了新的行字符,而且还散发出输出流。冲洗式Miight是最花时间的部分。因此,如果您只写
,它可能会更快std::cout << 2 * a << "n"; //Unix style line break
或
std::cout << 2 * a << "rn"; //Windows style line break
(注意:未经测试是否有效还是隐式齐平。)
- OpenGL大的3D纹理(>2GB)非常慢
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 为什么std::互斥需要很长的、非常不规则的时间来共享
- 缓慢提升ASIO
- G++ C++17 类模板参数推导在非常特殊的情况下不起作用
- 使用浮点数和双精度数的非常小数字的数学
- 在打开多个其他窗口时使用全屏窗口时帧速率非常低
- 我从int x[3]得到的一个非常奇怪的输出;
- 反向迭代器在C++中非常奇怪的行为
- 使用istringstearm和get行缓慢读取文件
- 当键值是 std 向量时,为什么使用 at in C++ 访问映射值如此缓慢?
- LLVM/OpenMP中的Mutex非常缓慢
- Postfix评估非常缓慢-优化
- Python和C 程序与子过程之间的沟通非常缓慢
- C 11多线程在神经网络中的性能非常缓慢
- kd树的构建非常缓慢
- 内存消耗迅速增加,然后非常缓慢地下降;内存泄漏
- PInvoke的回调非常缓慢
- c++编写和读取文本文件是非常缓慢的,任何替代方案
- 矢量的初始化非常缓慢