python与系统调用,为什么与C ++相比,Python中的系统调用这么慢?

在完成相同任务的意义上,我有2个相同的代码。一种代码是用python编写的,另一种则是用c ++编写的。所有代码要做的就是调用一个可执行文件(该可执行文件生成一个ascii文件)。在C ++中,我使用system()命令来调用可执行文件。在python中,我使用了很多东西,包括os.system subprocess.call subprocess.popen。

我意识到在解释python的同时,c ++是一种编译语言。而且我还意识到python调用的开销更大。但是C ++代码的工作速度比python代码快近100倍。 c ++时间约为0.004秒。 python时间约为0.35秒。

即使是简单的pwd命令,使用python所花费的时间也比使用c ++所花费的时间长10倍以上。如果开销是使python代码变慢的原因,python中是否有比我已经尝试过的选项更快的选项?

这是一个简单的python代码:

from os import system

from time import time

t0 = time();

system("pwd");

print"duration:",time()-t0;

这是c ++中的同一件事:

#include

#include

double diff(timespec start, timespec end) { return (end.tv_nsec-start.tv_nsec)/1e9; }

int main()

{

timespec t0, t1;

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, & t0);

system("pwd");

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, & t1);

std::cout <

";

return 0;

}

我用gcc编译c ++代码。您必须使用-lrt选项来使代码正确编译。

您可以自己运行代码。我的计时方法可能是错误的。但是如果可以的话,与C ++可执行文件相比,执行pwd命令所需的python脚本时间要长10倍以上

是的,编辑您的问题以包括代码,编译命令,时间安排。不要将system(3)库函数与syscalls(2)混淆

Python解释器在启动时会进行很多初始化。如果您只是在计时运行该脚本所需的时间,包括启动Python解释器,那就是为什么。

如果您还指出了操作系统,执行环境,Python版本,计时方法,这将对您有所帮助。

我机器上的@kindall最多需要Python解释器启动0.05秒

我编辑了我的帖子以包含代码。有人可以比较他们机器上的时间吗?

如果" 10倍长"相差几毫秒,那么这就是Python解释器的初始化。如果执行的命令花费相当长的时间,那么C ++和Python代码将花费基本上相同的时间。如果您要在某些外部脚本中循环执行新的Python进程,那就是您的问题。将循环内部化到Python脚本中。

@ore??gon,我认为那不是真的。我有2个调用相同的fortran可执行文件的代码。 c ++花费?0.004秒执行,而python脚本花费?0.35秒。它的时间超过80倍。

我仍然没有看到您的电话号码。我运行了您的新python示例,并得到了duration: 0.001123...。

好的,C ++可执行文件需要0.000131 ...

我正在python 2.7.3,kubuntu 13.04上进行测试。

我有旧的python 2.4.3,我的python解释器需要0.0028秒才能完成工作。无论哪种方式,C ++代码都快10倍(或更多)

当我们降低到.000x值时,速度要快10倍,这已经非常小了,我认为我们可以将其归纳为更多的解释语言,甚至是读取时间值的方式上的差异。对于这种时间水平有所不同的项目,请选择C!

我同意,但是为什么与我的pwd示例相比,执行时间更长的系统调用有更大的不同?正如我之前提到的,我有2个代码调用一个fortran可执行文件(我不知道fortran并且无法重写该程序)。我不能在这里提供所有代码,但是我已经以类似的方式测试了代码,我发现c ++可执行文件快了将近100倍!您会认为速度上的差异会从简单的系统调用变为"更复杂"的事物而减小。

我编写了一个小脚本,执行时间比您看到的要快得多。

td@timsworld2:~/tmp/so$ cat nothing.py

#!/usr/bin/env python

import subprocess

import sys

cmd = ['python', '-V'] if 'py' in sys.argv else ['pwd']

if 'shell' in sys.argv:

subprocess.call(' '.join(cmd), shell=True)

else:

subprocess.call(cmd)

td@timsworld2:~/tmp/so$ time ./nothing.py

/home/td/tmp/so

real    0m0.024s

user    0m0.012s

sys     0m0.008s

td@timsworld2:~/tmp/so$ time python nothing.py

/home/td/tmp/so

real    0m0.020s

user    0m0.012s

sys     0m0.004s

td@timsworld2:~/tmp/so$ time ./nothing.py py

Python 2.7.3

real    0m0.022s

user    0m0.016s

sys     0m0.000s

td@timsworld2:~/tmp/so$ time ./nothing.py sh

/home/td/tmp/so

real    0m0.020s

user    0m0.012s

sys     0m0.004s

td@timsworld2:~/tmp/so$

因此python脚本需要大约0.02秒的时间来执行。您是否在C ++中尝试过同样的事情?我使用linux,使用python的简单pwd命令花费约0.02秒,而使用c ++的同一命令更像是0.002秒

@rolb-好问题-我对几个有代表性的二进制文件中带有和不带有shell的python exec时间感兴趣。如果您发布了示例C程序,请不耐烦。到.02和.002的时间,我们可以归咎于python的建立时间。

请看我原始问题的编辑

您可以直接在python中使用execvp

import os

binary ="ls"

options = [binary,"-l"]

newpid = os.fork()

if newpid == 0:

# we are in the child process

os.execvp(binary, options)

os._exit(1)

os.wait()

print"executed","".join(options)

无论出于何种原因,该命令都可以正确执行,但是os.execvp命令之后的其余python脚本将被忽略。该可执行文件将被调用并正常运行。但即使os.execvp之后的简单print"here"也会被忽略

那是因为execvp替换了当前进程,在本例中为Python解释器。您可以先fork,然后再exec。看到我的编辑。

我在代码中使用了您的建议,但最后一行print"executed","".join(options)似乎没有执行。我的终端挂了。当我按Enter键时,该过程终止,并且终端上没有任何内容

您看到的是对stdout的争用。我更新了答案以使用os.wait()

效果很好。谢谢。不幸的是,执行速度并不快。它仍然需要与子过程方法相同的时间来执行。谢谢你的建议

C'exec'调用直接执行程序。

当Python的"系统"调用首先执行bash时,它将执行相关程序。

OP说他正在使用system函数,该函数也调用了shell。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值