前言
?
最近做了一個SDN流表的實驗,在這個實驗中,需要批量刪除大量的流表項,使用了shell腳本。然而,我的流表數(shù)據(jù)存放在python字典中,我一開始是考慮每次讀取一個字典并構造一條指令調(diào)用os.system(),然后發(fā)現(xiàn)這種方法效率非常糟糕。
我考慮問題可能出現(xiàn)在os.system()的調(diào)用上,可能它是一種非常費時間的調(diào)用(相比于直接用shell處理數(shù)據(jù))。
但是麻煩的是,這個SDN項目控制器基于python,我沒法直接用shell寫控制器程序。
所以然后想了一些辦法提升它的執(zhí)行效率,即本文內(nèi)容。
本文適用于有大量python數(shù)據(jù)需要shell進一步處理的環(huán)境。
?
實驗和方法
?
我寫了兩個程序,用來測試每次循環(huán)調(diào)用os.system的執(zhí)行時間以及直接使用shell的執(zhí)行時間,如下所示。
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
?
總結一下:
我考慮了循環(huán)1000次并打印的場景,其中,python程序里我統(tǒng)計了三個時間,分別是:
1、調(diào)用一次shell,shell循環(huán)1000次;
2、python生成shell指令,調(diào)用1000次os.system()執(zhí)行;
3、python生成shell執(zhí)行,調(diào)用1000次os.system(),同時這些os.system()并行執(zhí)行(最后有一個&)。
?
執(zhí)行結果:
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
?
結論
?
我們發(fā)現(xiàn),shell中執(zhí)行1000次循環(huán),其程序的本身運行時間僅需要0.018秒;
然而,如果使用python生成每一條指令并執(zhí)行os.system(),其時間需要0.16秒,大約相差10倍。
如果僅考慮python中調(diào)用os.system()的時間,那么僅調(diào)用一次os.system()的時間是循環(huán)生成指令并調(diào)用的約600分之一(0.0003 VS 0.1679)
在本實驗中,我們使用了os.system()的阻塞方法,若使用命令行末尾的 & 或者其他非阻塞方法,此時在理論上,我們僅需考慮python調(diào)用的時間。因此,在理想的理論情況上來看,在shell中直接執(zhí)行循環(huán)的效率能夠比在python中每次生成命令并調(diào)用os.system()的效率提升10到數(shù)百倍。
而利用 & 標識進行并行處理的情況和非并行的情況差不多(0.167 VS 0.171),其原因分析是:在這兩種情況下,都調(diào)用了1000次os.system(),而這可能是一種費時的方法,與簡單的執(zhí)行指令的時間開銷并不在一個數(shù)量級上。
?
綜上所述,若python需要循環(huán)調(diào)用shell,考慮到程序運行的效率,最關鍵的問題在于減少os.system類指令的調(diào)用次數(shù)。
解決的思路是:將循環(huán)寫入shell腳本,減少python調(diào)用shell的次數(shù)。如果shell腳本需要額外python程序中生成的參數(shù)作為輸入,將其作為環(huán)境變量,傳給shell腳本。
?
如何實現(xiàn)python將數(shù)組傳入shell,并在shell中循環(huán)執(zhí)行請參考我的另一篇博客:文章來源:http://www.zghlxwxcb.cn/news/detail-420722.html
https://blog.csdn.net/yyd19981117/article/details/117337487?spm=1001.2014.3001.5501文章來源地址http://www.zghlxwxcb.cn/news/detail-420722.html
到了這里,關于提升Python os.system調(diào)用Shell的執(zhí)行效率的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!