Python 效能快速優化

發表於2015-08-31

Python可能最容易扼殺你的想法,但不是最好的程式碼實現。儘管強烈反對過早優化,但在 Python 程式碼中一點點的優化都可能帶來巨大的效能提升。

解釋僅僅是目的,最正確的方式是天天使用 Python 程式設計,並且與效能影響相關。

  • %timeit (per line) 和 %prun (cProfile) 在 ipython 的互動式 Shell 中

當你的程式碼在工作時,分析你的程式碼,並且嘗試找出效能瓶頸在哪裡。這不與過早的優化是萬惡之源這個事實相反。這意味著一級優化,而不是進入冗長的優化序列。

更多的分析你的 Python 程式碼,你需要閱讀這個 python-performance-analysis

另外一個有趣的包, line_profiler 是一行一行的分析程式碼
分析 line_profiler

  • 降低方法呼叫次數,如果你有一個列表需要操作,傳遞整個列表,而不是遍歷整個列表並且傳遞每個元素給函式並返回。
  • 使用 xrange 代替 range。(在 Python2.x 中這樣做,因為 Python 3.x 中是預設的)

xrange 是 range 的 C 實現,著眼於有效的記憶體使用。

  • 對於大資料,使用 numpy,它比標準的資料結構好很多。
  • "".join(string) 比 + or += 好
  • while 1 比 while True 快
  • list comphrension > for loop > while

列表推導比迴圈遍歷列表快,但 while loop 是最慢的,需要使用一個外部計數器。

  • 使用 cProfilecStringIO 和 cPickle

一直使用 C 版本的模組

  • 使用區域性變數

區域性變數比全域性變數,內建型別以及屬性快。

  • 列表和迭代器版本存在 – 迭代器是記憶體效率和可伸縮性的。使用 itertools

建立生成器以及儘可能使用 yeild,它們比正常的列表方式更快。

下面是 Python 效能快速優化的第二部分。

  1. 使用 Map ,Reduce 和 Filter 代替 for 迴圈
  2. 校驗 a in b, 字典 或 set 比 列表 或 元組 更好
  3. 當資料量大的時候,儘可能使用不可變資料型別,他們更快 元組 > 列表
  4. 在一個列表中插入資料的複雜度為 O(n)
  5. 如果你需要操作列表的兩端,使用 deque
  6. del – 刪除物件使用如下
    1) python 自己處理它,但確保使用了 gc 模組
    2) 編寫 __del__ 函式
    3) 最簡單的方式,使用後呼叫 del
  7. time.clock()
  8. GIL(http://wiki.python.org/moin/GlobalInterpreterLock) – GIL is a daemon

GIL 僅僅允許一個 Python 的原生執行緒來執行每個程式。阻止 CPU 級別的並行,嘗試使用 ctypes 和 原生的 C 庫來解決它,當你達到 Python 優化的最後,總是存在一個選項,可以使用原生的 C 重寫慢的函式,通過 Python 的 C 繫結使用它,其他的庫如 gevent 也是致力於解決這個問題,並且獲得了成功。

TL,DR:當你寫程式碼了,過一遍資料結構,迭代結構,內建和為 GIL 建立 C 擴充套件,如有必要。

更新:multiprocessing 是在 GIL 的範圍之外,這意味著你可以使用 multiprocessing 這個標準庫來執行多個程式。

看下我的 2013 的印度 PyCon 演講

相關文章