Python-02進階-06代碼優化工具

代碼優化工具

Python作爲高級編程語言,對於其性能要求也越來越注重。

本文總結:

性能優化的主要方法: 多進程處理,工具檢測性能消耗完善代碼,使用Cython擴展等。

說明

代碼優化工具列表

代碼優化工具列表

優化工具 工具說明
PyLint 語法檢查工具
vprof 運行時間和內存分析器。圖形化工具。
cProfile 查詢消耗時間最久的方法函數
line_profile 查看耗時函數中的行耗時
timeit 模塊計算代碼執行時間
memory_profiler 診斷內存的用量

代碼常見性能優化指標

機器性能指標

  • CPU
  • IO
  • MEM 內存
  • NET 網絡

常見性能指標

  • 響應時間
  • 錯誤率
  • 吞吐率
  • 執行時間
  • 內存佔用

優化方法小結

方法小結:

  • 使用 cProfile, cStringIO 和 cPickle等用c實現相同功能
  • 使用 c 擴展。目前主要有CPython(python最常見的實現的方式)原生API, ctypes,Cython,cffi三種方式
  • 並行編程 multiprocessing
  • 大殺器PyPy
  • CUDA編程

相關資源

Python應用與優化所必備的6個基本庫

運行時間-vprof圖表化

vprof代碼檢測工具
vprof官網

vprof簡單使用

pip3 install vprof
# 直接運行代碼
vprof -c h test.py
# 帶輸入參數
vprof -c cmh "testscript.py --foo --bar"

運行時間-gprof2dot圖表化(強烈推薦)

gprof2dot官網

cProfile+gprof2dot簡單使用

sudo pip3 install gprof2dot
# 先用cProfile生成分析報告
python3 -m cProfile -o output.pstats test.py
# 使用 gprof2dot 畫圖
gprof2dot -f pstats output.pstats | dot -Tpng -o output.png

編譯優化-PyPy

PyPy是用RPython(CPython的子集)實現的Python,使用了Just-in-Time(JIT)編譯器,即動態編譯器,
與靜態編譯器(如gcc,javac等)不同,它是利用程序運行的過程的數據進行優化。
如果python程序中含有C擴展(非cffi的方式),JIT的優化效果會大打折扣,甚至比CPython慢(比Numpy)。

所以在PyPy中最好用純Python或使用cffi擴展。

PyPy優勢在於使用JIT動態編譯,對於運行的函數會生成一個類C的函數。
編譯成機器碼,下次調用函數時,會直接調用機器碼,速度得到質的飛躍。
但是由於本身編譯機器碼需要時間。

所以很多 JIT 實現都會先解釋執行,然後確定了一段代碼經常被執行之後,再進行編譯。並且分多層 JIT,比較初級的對編譯出來的機器碼不做比較複雜的優化.

運行時間-上下文管理器

用上下文管理器測量部分代碼運行時間

from time import clock
class Timer(object):
    def __init__(self, verbose=False):
        self.verbose = verbose
 
    def __enter__(self):
        self.start = clock()
        return self
 
    def __exit__(self, *args):
        self.end = clock()
        self.secs = self.end - self.start
        self.msecs = self.secs * 1000  # millisecs
        if self.verbose:
            print 'elapsed time: %f ms' % self.msecs
 
if __name__ == "__main__":
 
    with Timer() as t:
        replace_str = ""
        for i, char in enumerate(orignal_str * 10000):
            c = char if char != " " else "-"
            replace_str += c
    print t.secs

內存-objgraph

objgraph是一個非常輕巧的工具,但在排查內存泄露的時候非常有用。
objgraph的代碼很短,只有一個文件,其主要依靠標準庫中的gc模塊來獲取對象之間的創建引用關係。objgraph使用起來十分簡單,

# 列出最多實例的類型
objgraph.show_most_common_types(shortnames=False)
# 顯示兩次調用之間的對象數量變化
objgraph.show_growth(limit=None)
# 獲取指定類型的對象
objgraph.by_type('Foobar')
# 查找反向引用
objgraph.find_backref_chain(obj, objgraph.is_proper_module)

在遇到內存泄露問題時候首先考慮下用objgraph來進行查看,沒有問題的時候也可以學習下它的代碼,可以極大瞭解gc模塊的應用。

內存-tracemalloc

tracemalloc是用來分析Python程序內存分配的工具,使用上也很簡單,

import tracemalloc
tracemalloc.start()

# ... run your application ...

snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')

snapshot結果中可以看到每個模塊最終創建分配的內存大小,在追查內存問題上很有幫助。
Python 3.5.x之後將tracemalloc集成到了標準庫當中

編碼規範-autopep8

Autopep8是一個將python代碼自動編排的一個工具,它使用pep8工具來決定代碼中的那部分需要被排。
,Autopep8可以修復大部分pep8工具中報告的排版問題。很多人都知道 Ctrl+Alt+L 也可以排版,快捷鍵只是可以簡單的排版。
跟Autopep8是無法相比的。

# autopep8 使用命令
autopep8 --in-place --aggressive --aggressive file.py
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章