給Python加速(性能加速的方法)

  • 2020 年 1 月 10 日
  • 筆記

首先提高代碼的性能不能以改變代碼功能為代價。

簡而言之,按照原文說的:

  • 1.首先將代碼寫對
  • 2.測試代碼是否正確執行
  • 3.如果代碼效率不高就分析是哪個部分造成的。
  • 4.優化這個部分
  • 5.從第二步開始重複這個部分

詳細的解讀包括:

選擇一個正確的數據結構。

這個說法深有體會。Python中多變的數據結構可以造成很大的差異,使用一個set就可以事半功倍。甚至一個自己定義的數據結構,對於內存,運算速度,處理方式等都有很大的影響。

進行排序

我在項目中也遇到過,爬取的幾百萬的數據URL需要進行鑒別,哪些數據抓取了哪些沒有,抓取的部分還有重複。使用if x in y這種格式,則需要o(m*n)的時間複雜度。而兩邊都對URL進行排序後,則可以使用兩個指針輕鬆搞定。

示例中使用了operator 模塊的itemgetter() 函數,進行了快速的分類,優雅而簡潔。

n = 1  import operator  nlist.sort(key=operator.itemgetter(n))

字符串組合

編寫大字符串的時候,不建議使用加號拼接字符串。使用join,%s(py3中使用format方法)等官方的方法效果更好。

循環的使用

如果使用for循環進行簡單而大量的操作,不妨試試map()函數,或者python2.0中就已經有的list方法直接生成。或者使用迭代器進行循環的操作。

避免使用點方法

如上,需要使用list.append()方法的時候,這些方法都是需要在每次調用的時候重新確定(原文reevaluated)的,所以可以提前代替,如re.compile()方法。

upper = str.upper  newlist = []  append = newlist.append  for word in oldlist:      append(upper(word))

使用局部變量

可以將一些代碼函數化,從而將變量轉為局部變量,Python獲取局部變量比使用全局變量要快得多。

原文最終做了一個比較實驗,將38470個單詞轉換成大寫,結果是:

Version Time (seconds)  Basic loop 3.47  Eliminate dots 2.45  Local variable & no dots 1.79  Using map function 0.54

可見使用map具有巨大的優勢。

初始化字典元素

字典的當前使用新技巧包括:使用keyError來定位沒有的key,使用get()方法來返回鍵對應的值。字典中還有collections模塊中較多的:defaultdict,OrderedDict類等。

首先在頭部寫明 import 聲明

大量的import會影響Python的性能。雖然隨處可以import, 但最好在代碼的頭部集中寫明。

數據的聚合

一次將多個數據聚合起來傳遞給函數比多次調用函數的開銷要小得多。

減少執行語句的數量

Python中有一個定期檢查線程是否該運行的函數。這個函數的大量調用會影響性能。最好我們可以設置這個值為較大的數,或者使用少的執行語句而以空間換時間。

Python不是C

移位不一定比加法快。Python是一個高級語言,調用底層不一定快。

使用xrange而不是range

在py3中不用考慮這一條。因為range已經優化了。

對代碼進行優化

有時候有些函數你知道不會執行,就可以直接省略。減少不必要的操作。

使用profile

import profile  profile.run('main()')