歡迎您光臨本站 註冊首頁

Python 代碼性能優化技巧

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  

選擇了腳本語言就要忍受其速度,這句話在某種程度上說明了 python 作為腳本的一個不足之處,那就是執行效率和性能不夠理想,特別是在 performance 較差的機器上,因此有必要進行一定的代碼優化來提高程序的執行效率。如何進行 Python 性能優化,是本文探討的主要問題。本文會涉及常見的代碼優化方法,性能優化工具的使用以及如何診斷代碼的性能瓶頸等內容,希望可以給 Python 開發人員一定的參考。

 

Python 代碼優化常見技巧

代碼優化能夠讓程序運行更快,它是在不改變程序運行結果的情況下使得程序的運行效率更高,根據 80/20 原則,實現程序的重構、優化、擴展以及文檔相關的事情通常需要消耗 80% 的工作量。優化通常包含兩方面的內容:減小代碼的體積,提高代碼的運行效率。

改進演算法,選擇合適的數據結構

一個良好的演算法能夠對性能起到關鍵作用,因此性能改進的首要點是對演算法的改進。在演算法的時間複雜度排序上依次是:

O(1) -> O(lg n) -> O(n lg n) -> O(n^2) -> O(n^3) -> O(n^k) -> O(k^n) -> O(n!)

因此如果能夠在時間複雜度上對演算法進行一定的改進,對性能的提高不言而喻。但對具體演算法的改進不屬於本文討論的範圍,讀者可以自行參考這方面資料。下面的內容將集中討論數據結構的選擇。

  • 字典 (dictionary) 與列表 (list)

Python 字典中使用了 hash table,因此查找操作的複雜度為 O(1),而 list 實際是個數組,在 list 中,查找需要遍歷整個 list,其複雜度為 O(n),因此對成員的查找訪問等操作字典要比 list 更快。


清單 1. 代碼 dict.py
01 from time import time
02 t = time()
03 list = ['a','b','is','python','jason','hello','hill','with','phone','test',
04 'dfdf','apple','pddf','ind','basic','none','baecr','var','bana','dd','wrd']
05 #list = dict.fromkeys(list,True)
06 print list
07 filter = []
08 for i in range (1000000):
09 for find in ['is','hat','new','list','old','.']:
10 if find not in list:
11 filter.append(find)
12 print "total run time:"
13 print time()-t
上述代碼運行大概需要 16.09seconds。如果去掉行 #list = dict.fromkeys(list,True) 的註釋,將 list 轉換為字典之後再運行,時間大約為 8.375 seconds,效率大概提高了一半。因此在需要多數據成員進行頻繁的查找或者訪問的時候,使用 dict 而不是 list 是一個較好的選擇。
  • 集合 (set) 與列表 (list)

set 的 union, intersection,difference 操作要比 list 的迭代要快。因此如果涉及到求 list 交集,並集或者差的問題可以轉換為 set 來操作。


清單 2. 求 list 的交集:
01 from time import time
02 t = time()
03 lista=[1,2,3,4,5,6,7,8,9,13,34,53,42,44]
04 listb=[2,4,6,9,23]
05 intersection=[]
06 for i in range (1000000):
07 for a in lista:
08 for b in listb:
09 if a == b:
10 intersection.append(a)
11  
12  
13 print "total run time:"
14 print time()-t

上述程序的運行時間大概為:

total run time:
38.4070000648

清單 3. 使用 set 求交集
1 from time import time
2 t = time()
3 lista=[1,2,3,4,5,6,7,8,9,13,34,53,42,44]
4 listb=[2,4,6,9,23]
5 intersection=[]
6 for i in range (1000000):
7 list(set(lista)&set(listb))
8 print "total run time:"
9 print time()-t
改為 set 后程序的運行時間縮減為 8.75,提高了 4 倍多,運行時間大大縮短。讀者可以自行使用表 1 其他的操作進行測試。
表 1. set 常見用法
語法 操作 說明
set(list1) | set(list2) union 包含 list1 和 list2 所有數據的新集合
set(list1) & set(list2) intersection 包含 list1 和 list2 中共同元素的新集合
set(list1) - set(list2) difference 在 list1 中出現但不在 list2 中出現的元素的集合

對循環的優化

對循環的優化所遵循的原則是盡量減少循環過程中的計算量,有多重循環的盡量將內層的計算提到上一層。 下面通過實例來對比循環優化后所帶來的性能的提高。程序清單 4 中,如果不進行循環優化,其大概的運行時間約為 132.375。


清單 4. 為進行循環優化前
01 from time import time
02 t = time()
03 lista = [1,2,3,4,5,6,7,8,9,10]
04 listb =[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,0.01]
05 for i in range (1000000):
06 for a in range(len(lista)):
07 for b in range(len(listb)):
08 x=lista[a]+listb[b]
09 print "total run time:"
10 print time()-t

現在進行如下優化,將長度計算提到循環外,range 用 xrange 代替,同時將第三層的計算 lista[a] 提到循環的第二層。


清單 5. 循環優化后
01 from time import time

好文,頂一下
(0)
0%
文章真差,踩一下
(0)
0%
------分隔線----------------------------
  • 上一篇:EasyMock教程--入門指南
  • 下一篇:安裝 Mate 1.4在Ubuntu 12.04等系統中
  • 我要評論!
  • 收藏
  • 挑錯
  • 推薦
  • 列印


把開源帶在你的身邊-精美linux小紀念品
文章分類
    新聞動態 企鵝看世界 軟體更新資訊 新手入門 資料庫類 系統安全 系統管理 網路管理 使用經驗 編程開發 企業應用 硬體相關 Unix家族 觀點評論 人物介紹 技術前沿 專題 開源生活 開源美圖 英文資料 Eden團隊出品 開源軟體庫
軟體導航
  • 發行版類 內核相關 伺服器類 模擬模擬 文件管理
  • 系統安全 多媒體類 硬體工具 編程開發 網路熱門
  • 雜類工具 網路工具 圖形圖像 閱讀編輯 書籍資料
  • 遊戲軟體 辦公軟體 數據備份 中文相關 系統管理
  • 科學計算 資料庫類 XWin系統
論壇導航
  • 初級應用-> 新手入門 | 伺服器應用 | 中文化 | 軟體使用交流 | 硬體驅動 | 圖片秀 | 茶館
  • 高級應用->資料庫 | 系統安全 | 嵌入式應用|
  • 編程開發-> C/C++(STL/boost) | 內核 | RAD|Perl/PHP/Python | JAVA/XML | Shell
  • 發行版-> Redhat和Fedora | Debian | Gentoo | Slackware/Suse | Mandrake/Mandriva
  • Unix ->FreeBSD | Solaris | 其他Unix討論
論壇精華
一周熱點

[火星人 ] Python 代碼性能優化技巧已經有871次圍觀

http://coctec.com/docs/linux/show-post-65141.html