python高效能編程方法一

來源:互聯網
上載者:User
閱讀 Zen of Python,在Python解析器中輸入 import this. 一個犀利的Python新手可能會注意到"解析"一詞, 認為Python不過是另一門指令碼語言. "它肯定很慢!"

毫無疑問Python程式沒有編譯型語言高效快速. 甚至Python擁護者們會告訴你Python不適合這些領域. 然而,YouTube已用Python服務於每小時4千萬視頻的請求. 你所要做的就是編寫高效的代碼和需要時使用外部實現(C/C++)代碼. 這裡有一些建議,可以協助你成為一個更好的Python開發人員:

1. 使用內建函數: 你可以用Python寫出高效的代碼,但很難擊敗內建函數. 經查證. 他們非常快速.2.使用join()連接字串. 你可以使用 "+" 來連接字串. 但由於string在Python中是不可變的,每一個"+"操作都會建立一個新的字串並複製舊內容. 常見用法是使用Python的數組模組單個的修改字元;當完成的時候,使用 join() 函數建立最終字串.

>>> #This is good to glue a large number of strings

>>> for chunk in input():

>>> my_string.join(chunk)

3. 使用Python多重賦值,交換變數

這在Python中即優雅又快速:

>>> x, y = y, x

這樣很慢:

>>> temp = x

>>> x = y

>>> y = temp

4. 盡量使用局部變數

Python 檢索局部變數比檢索全域變數快. 這意味著,避免 "global" 關鍵字.

5. 盡量使用 "in"

使用 "in" 關鍵字. 簡潔而快速.

>>> for key in sequence:

>>> print “found”

6. 使用消極式載入加速

將 "import" 聲明移入函數中,僅在需要的時候匯入. 換句話說,如果某些模組不需馬上使用,稍後匯入他們. 例如,你不必在一開使就匯入大量模組而加速程式啟動. 該技術不能提高整體效能. 但它可以協助你更均衡的分配模組的載入時間.

7. 為無限迴圈使用 "while 1"

有時候在程式中你需一個無限迴圈.(例如一個監聽通訊端的執行個體) 儘管 "while true" 能完成同樣的事, 但 "while 1" 是單步運算. 這招能提高你的Python效能.

>>> while 1:

>>> #do stuff, faster with while 1

>>> while True:

>>> # do stuff, slower with wile True

8. 使用list comprehension

從Python 2.0 開始,你可以使用 list comprehension 取代大量的 "for" 和 "while" 塊. 使用List comprehension通常更快,Python解析器能在迴圈中發現它是一個可預測的模式而被最佳化.額外好處是,list comprehension更具可讀性(函數式編程),並在大多數情況下,它可以節省一個額外的計數變數。例如,讓我們計算1到10之間的偶數個數:

>>> # the good way to iterate a range

>>> evens = [ i for i in range(10) if i%2 == 0]

>>> [0, 2, 4, 6, 8]

>>> # the following is not so Pythonic

>>> i = 0

>>> evens = []

>>> while i < 10:

>>> if i %2 == 0: evens.append(i)

>>> i += 1

>>> [0, 2, 4, 6, 8]

9. 使用xrange()處理長序列:

這樣可為你節省大量的系統記憶體,因為xrange()在序列中每次調用只產生一個整數元素。而相反 range(),它將直接給你一個完整的元素列表,用於迴圈時會有不必要的開銷。

10. 使用 Python generator:

這也可以節省記憶體和提高效能。例如一個視頻流,你可以一個一個位元組塊的發送,而不是整個流。例如,

>>> chunk = ( 1000 * i for i in xrange(1000))

>>> chunk

>>> chunk.next()

0

>>> chunk.next()

1000

>>> chunk.next()

2000

11. 瞭解itertools模組:

該模組對迭代和組合是非常有效。讓我們產生一個列表[1,2,3]的所有排列組合,僅需三行Python代碼:

>>> import itertools

>>> iter = itertools.permutations([1,2,3])

>>> list(iter)

[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

12. 學習bisect模組保持列表排序:

這是一個免費的二分尋找實現和快速插入有序序列的工具。也就是說,你可以使用:

>>> import bisect

>>> bisect.insort(list, element)

你已將一個元素插入列表中, 而你不需要再次調用 sort() 來保持容器的排序, 因為這在長序列中這會非常昂貴.

13. 理解Python列表,實際上是一個數組:

Python中的列表實現並不是以人們通常談論的電腦科學中的普通單鏈表實現的。Python中的列表是一個數組。也就是說,你可以以常量時間O(1) 檢索列表的某個元素,而不需要從頭開始搜尋。這有什麼意義呢? Python開發人員使用列表對象insert()時, 需三思. 例如:>>> list.insert(0,item)

在列表的前面插入一個元素效率不高, 因為列表中的所有後續下標不得不改變. 然而,您可以使用list.append()在列表的尾端有效添加元素. 挑先deque,如果你想快速的在兩插入或時。它是快速的,因為在Python中的deque用雙鏈表實現。不再多說。

14. 使用dict 和 set 測試成員: 檢查一個元素是在dicitonary或set是否存在 這在Python中非常快的。這是因為dict和set使用雜湊表來實現。尋找效率可以達到O(1)。因此,如果您需要經常檢查成員,使用 set 或 dict做為你的容器.

>>> mylist = ['a', 'b', 'c'] #Slower, check membership with list:

>>> ‘c’ in mylist

>>> True

>>> myset = set(['a', 'b', 'c']) # Faster, check membership with set:

>>> ‘c’ in myset:

>>> True

15. 使用Schwartzian Transform 的 sort():

原生的list.sort()函數是非常快的。 Python會按自然順序排序列表。有時,你需要非自然順序的排序。例如,你要根據伺服器位置排序的IP地址。 Python支援自訂的比較,你可以使用list.sort(CMP()),這會比list.sort()慢,因為增加了函數調用的開銷。如果效能有問 題,你可以申請Guttman-Rosler Transform,基於Schwartzian Transform. 它只對實際的要用的演算法有興趣,它的簡要工作原理是,你可以變換列表,並調用Python內建list.sort() - > 更快,而無需使用list.sort(CMP() )->慢。

16. Python裝飾器緩衝結果:

“@”符號是Python的裝飾文法。它不只用於追查,鎖或日誌。你可以裝飾一個Python函數,記住調用結果供後續使用。這種技術被稱為memoization的。下面是一個例子:

>>> from functools import wraps

>>> def memo(f):

>>> cache = { }

>>> @wraps(f)

>>> def wrap(*arg):

>>> if arg not in cache: cache['arg'] = f(*arg)

>>> return cache['arg']

>>> return wrap

我們也可以對 Fibonacci 函數使用裝飾器:

>>> @memo

>>> def fib(i):

>>> if i < 2: return 1

>>> return fib(i-1) + fib(i-2)

這裡的關鍵思想是:增強函數(裝飾)函數,記住每個已經計算的Fibonacci值;如果它們在緩衝中,就不需要再計算了.

17. 理解Python的GIL(全域解譯器鎖):

GIL是必要的,因為CPython的記憶體管理是非安全執行緒的。你不能簡單地建立多個線程,並希望Python能在多核心的機器上運行得更快。這是因為 GIL將會防止多個原生線程同時執行Python位元組碼。換句話說,GIL將序列化您的所有線程。然而,您可以使用線程管理多個派生進程加速程式,這些程 序獨立的運行於你的Python代碼外。

18. 像熟悉文檔一樣的熟悉Python原始碼:

Python有些模組為了效能使用C實現。當效能至關重要而官方文檔不足時,可以自由探索原始碼。你可以找到底層的資料結構和演算法。 Python的源碼庫就是一個很棒的地方:http://svn.python.org/view/python/trunk/Modules

結論:

這些不能替代大腦思考. 開啟引擎蓋充分瞭解是開發人員的職責,使得他們不會快速拼湊出一個垃圾設計. 本文的Python建議可以協助你獲得好的效能. 如果速度還不夠快, Python將需要藉助外力:分析和運行外部代碼.我們將在本文的第二部分中涉及.

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.