提升Python os.system调用Shell的执行效率

前言

 

最近做了一个SDN流表的实验,在这个实验中,需要批量删除大量的流表项,使用了shell脚本。然而,我的流表数据存放在python字典中,我一开始是考虑每次读取一个字典并构造一条指令调用os.system(),然后发现这种方法效率非常糟糕。

我考虑问题可能出现在os.system()的调用上,可能它是一种非常费时间的调用(相比于直接用shell处理数据)。

但是麻烦的是,这个SDN项目控制器基于python,我没法直接用shell写控制器程序。

所以然后想了一些办法提升它的执行效率,即本文内容。

本文适用于有大量python数据需要shell进一步处理的环境。

 

实验和方法

 

我写了两个程序,用来测试每次循环调用os.system的执行时间以及直接使用shell的执行时间,如下所示。

Python:

import os
import time

start1=time.clock()
os.system('./shell_test.sh')
end1=time.clock()

start2=time.clock()
for i in range(0,1001):
	command = 'echo ' + str(i)
	os.system(command)
end2=time.clock()

start3=time.clock()
for i in range(0,1001):
	command = 'echo ' + str(i) + ' &'
	os.system(command)
end3=time.clock()

print 'For Cycle in Shell: ' + str(end1-start1) + 's'
print 'For Cycle in Python Command: ' + str(end2-start2) + 's'
print 'For Cycle in Python Command with &: ' + str(end3-start3) + 's'

Shell:

#! /bin/bash

i=0

start=$(date +%s%N)
start_ms=${start:0:16}

while [ $i -le 1000 ]
do
	echo "$i"
	let i=i+1
done

end=$(date +%s%N)
end_ms=${end:0:16}
echo "cost time is: "
echo "scale=6; ($end_ms - $start_ms)/1000000" | bc

 

总结一下:

我考虑了循环1000次并打印的场景,其中,python程序里我统计了三个时间,分别是:

1、调用一次shell,shell循环1000次;

2、python生成shell指令,调用1000次os.system()执行;

3、python生成shell执行,调用1000次os.system(),同时这些os.system()并行执行(最后有一个&)。

 

执行结果:

For Cycle in Shell: 0.000317s(cost time is: .018886)
For Cycle in Python Command: 0.167936s
For Cycle in Python Command with &: 0.171174s

 

结论

 

我们发现,shell中执行1000次循环,其程序的本身运行时间仅需要0.018秒;

然而,如果使用python生成每一条指令并执行os.system(),其时间需要0.16秒,大约相差10倍。

如果仅考虑python中调用os.system()的时间,那么仅调用一次os.system()的时间是循环生成指令并调用的约600分之一(0.0003 VS 0.1679)

在本实验中,我们使用了os.system()的阻塞方法,若使用命令行末尾的 & 或者其他非阻塞方法,此时在理论上,我们仅需考虑python调用的时间。因此,在理想的理论情况上来看,在shell中直接执行循环的效率能够比在python中每次生成命令并调用os.system()的效率提升10到数百倍。

而利用 & 标识进行并行处理的情况和非并行的情况差不多(0.167 VS 0.171),其原因分析是:在这两种情况下,都调用了1000次os.system(),而这可能是一种费时的方法,与简单的执行指令的时间开销并不在一个数量级上。

 

综上所述,若python需要循环调用shell,考虑到程序运行的效率,最关键的问题在于减少os.system类指令的调用次数。

解决的思路是:将循环写入shell脚本,减少python调用shell的次数。如果shell脚本需要额外python程序中生成的参数作为输入,将其作为环境变量,传给shell脚本。

 

如何实现python将数组传入shell,并在shell中循环执行请参考我的另一篇博客:

https://blog.csdn.net/yyd19981117/article/details/117337487?spm=1001.2014.3001.5501

你可能感兴趣的:(bug记录和问题解决,python,shell)