檢測Python程序的執行效率


無意中被問到代碼執行效率的問題,那就總結一下檢測代碼執行效率的幾種方式:

一、裝飾器

在函數上加裝飾器,來得到函數的執行時間。

def cst_time(func, *args, **kwargs):
    def wrapper(*args, **kwargs):
        start = time.time()
        ret = func(*args, **kwargs)
        end = time.time()
        timestrap = end -start
        print('function %s running time is %s'%(func.__name__,timestrap))
        return ret
    return wrapper

二、timeit模塊

用timeit模塊來計算代碼執行時間:

python3 -m timeit -n 4 -r 5 -s "import binaryTree" "binaryTree"    #其中binaryTree表示python腳本文件名

或

python3 -m timeit -n 4 -r 5 -s "import binaryTree" "binaryTree.functionname"    #可以指定腳本中某個具體的函數

參數:

  -m mod : run library module as a script (terminates option list)

執行結果:

4 loops, best of 5: 0.0792 usec per loop

這表示測試了4次,平均每次測試重復5次,最好的測試結果是0.0792秒。

如果不指定測試或重復次數,默認值為10次測試,每次重復5次。

三、Linux的time命令

time -p python3 multiTree.py

執行結果:

real 0.09              # 執行腳本的總時間
user 0.04             # 執行腳本消耗的CPU時間    
sys 0.00               # 執行內核函數消耗的時間

# real - (user + sys)的時間差,就是消耗在I/O等待和執行其他任務消耗的時間。

四、cProfile模塊

如果想知道每個函數消耗的多少時間,以及每個函數執行了多少次,可以用CProfile模塊。

python3 -m cProfile -s cumulative multiTree.py 

執行結果:

五、line_Profiler模塊

使用line_Profiler可以給出執行每行代碼所占用的CPU時間。

$ sudo pip3 install line_Profiler

 

用@profile 指定去檢測那個函數,不需要導入模塊。

@profile
def random_sort2(n):
    l = [random.random() for i in range(n)]
    l.sort()
    return l
 
if __name__ == "__main__":
    random_sort2(2000000)

可以通過如下命令逐行掃描每行代碼的執行情況:

$ kernprof -l -v timing_functions.py

其中-l表示逐行解釋,-v表示表示輸出詳細結果。通過這種方法,我們看到構建數組消耗了44%的計算時間,而sort()方法消耗了剩余的56%的時間。

六、memory_profiler模塊

逐行檢測每行代碼內存的使用的情況。但使用這個模塊會讓代碼運行更慢。

$ sudo pip3 install memory_profiler

安裝 psutil模塊,會讓memory_profiler運行更快。

$ sudo pip3 install psutil  

在函數上加 @profile 裝飾器來指定需要追蹤的函數。

執行如下命令,查看結果:

$ python3 -m memory_profiler timing_functions.py

七、guppy模塊

通過這個包可以知道在代碼執行的每個階段中,每種類型(str、tuple、dict等)分別創建了多少對象。

$ pip3 install guppy

 將其添加到代碼中:

from guppy import hpy
 
def random_sort3(n):
    hp = hpy()
    print( "Heap at the beginning of the functionn", hp.heap())
    l = [random.random() for i in range(n)]
    l.sort()
    print( "Heap at the end of the functionn", hp.heap())
    return l
 
if __name__ == "__main__":
    random_sort3(2000000)  

 執行命令:

$ python3 timing_functions.py

 查看結果:

 

 

 

 

-----------------------------------------------------------------------------------------------------------------------------------------------------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM