三種提高Python程式碼效能的簡便方法

zhongpeijiaoyu發表於2020-08-03

  在網際網路程式語言盛行的今天,Python是比較流行的程式語言之一。但很多程式設計師對於Python程式碼效能的方法並不瞭解。今天這裡主要為大家介紹三種提高Python程式碼效能的簡便方法,即是一是基準,基準,基準、二是儘可能避免迴圈和三使用Cython編譯Python模組三點內容。通過這三種方法,如果您想在Jupyter膝上型電腦中利用Cython,可以使用%% Cython魔術,最終以最小的編譯函式。

  1.基準,基準,基準

  基準測試聽起來像是一個繁瑣的過程,但是如果您已經將工作程式碼分為多個函式,則可以像在要分析的函式中新增裝飾器一樣簡單。

  首先,讓我們安裝line_profiler,以便我們可以測量函式中每行程式碼所花費的時間:

  pip3 install line_profiler

  這提供了一個裝飾器(@profile),可用於逐行對程式碼中的任何函式進行基準測試。例如,假設我們有以下程式碼:

  #filename: test.py@profiledef sum_of_lists(ls):www.zpedu.com/

  ‘’’Calculates the sum of an input list of lists’’’

  s = 0

  for l in ls:

  for val in l:

  s += val

  return s

  #create a list of lists

  smallrange = list(range(10000))

  inlist = [smallrange, smallrange, smallrange, smallrange]#now sum them

  list_sum = sum_of_lists(inlist)

  print(list_sum)

  這將在呼叫sum_of_lists函式時對其進行概要分析 -請注意函式定義上方的@profile裝飾器。

  現在,我們可以通過執行以下操作來分析程式碼:

  python3 -m line_profiler test.py

  這給了我們:

  第5列顯示了在每一行上花費的執行時的百分比-這將使您指向最需要優化的程式碼部分,因為這是花費大部分執行時的地方。

  請記住,此基準測試庫具有大量開銷,但是它非常適合在程式碼中查詢弱點並將其替換為更有效率的東西。

  要在Jupyter筆記本中執行line_profiler,請檢視%% lprun magic命令。

  2.儘可能避免迴圈

  在許多情況下,在python中使用map,list comprehensions或numpy.vectorize(通常是最快的)之類的操作而不是迴圈,可以在不進行大量工作的情況下顯著提高效能,因為這些操作在內部進行了優化。讓我們通過將巢狀迴圈替換為map和sum來稍微修改前面的示例:

  #filename: test_map.pydef sum_of_lists_map(ls):

  ‘’’Calculates the sum of an input list of lists’’’

  return(sum(list(map(sum,ls))))#create a list of lists

  smallrange = list(range(10000))

  inlist = [smallrange,smallrange,smallrange,smallrange]#now sum them

  list_sum = sum_of_lists_map(inlist)

  print(list_sum)

  讓我們將新地圖版本定時1000次,以瞭解它們與原始地圖相比的效果:

  地圖版本比原始版本快6倍以上!

  3.使用Cython編譯Python模組

  如果您根本不想修改專案,但仍然希望免費獲得一些效能提升,則Cython是您的朋友。

  儘管Cython不是通用的python C編譯器,但是Cython允許您將python模組編譯為共享物件檔案(.so),可以由您的主要python指令碼載入。

  為此,您將需要在計算機上安裝Cython以及C編譯器:

  pip3 install cython

  如果您使用的是Debian,則可以執行以下操作下載GCC:

  sudo apt install gcc

  讓我們將示例程式碼分成2個檔案,分別名為test_cython.py和test_module.pyx:

  #filename: test_module.pyxdef sum_of_lists(ls):

  ‘’’Calculates the sum of an input list of lists’’’

  s = 0

  for l in ls:

  for val in l:

  s += val

  return s

  我們的主檔案必須從test_module.pyx檔案匯入此功能:

  #filename: test_cython.pyfrom test_module import *#create a list of lists

  smallrange = list(range(10000))

  inlist = [smallrange,smallrange,smallrange,smallrange]#now sum them

  list_sum = sum_of_lists(inlist)

  print(list_sum)

  現在讓我們定義一個setup.py檔案來使用Cython編譯我們的模組:

  #filename: setup.pyfrom setuptools import setupfrom Cython.Build import cythonize

  setup(

  ext_modules = cythonize(“test_module.pyx”)

  )

  最後,是時候編譯我們的模組了:

  python3 setup.py build_ext –inplace

  現在,通過對它們進行1000次計時,可以看到該版本與原始版本相比有何改進:

  在這種情況下,Cython的速度比原始速度提高了近2倍,但這取決於您要優化的程式碼型別。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章