成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

猛戳加速鍵:你擁有這些Python加速技能嗎?

開發 后端
但其實很多時候,Python的效率并沒有達到它應有的速度,有一些讓它馬達開足的小技巧,一起來學習吧!

本文轉載自公眾號“讀芯術”(ID:AI_Discovery)。

Python有時用起來確實很慢,我敢打賭你肯定抱怨過這一點,尤其是那些用慣了C,C ++或Java的人。

但其實很多時候,Python的效率并沒有達到它應有的速度,有一些讓它馬達開足的小技巧,一起來學習吧!

[[331840]]

1. 避免使用全局變量

  1. import mathsize = 10000 
  2. for x in range(size): 
  3.     for y in range(size): 
  4.         z = math.sqrt(x) + math.sqrt(y) 

許多程序員一開始都會用Python語言編寫一些簡單的腳本。編寫腳本時,通常直接使用全局變量,就像上面這段代碼。

但由于全局變量和局部變量的實現方式不同,全局變量中定義的代碼要比在函數中定義的函數運行起來慢得多。把腳本語句放入函數中,通常運行速度可提高15%-30%。如下所示:

  1. import mathdef main(): 
  2.     size = 10000 
  3.     for x in range(size): 
  4.         for y in range(size): 
  5.             z = math.sqrt(x) +math.sqrt(y)main() 

2. 避免數據重復

避免無意義的數據復制

  1. def main(): 
  2.     size = 10000 
  3.     for _ in range(size): 
  4.         value = range(size) 
  5.         value_list = [x for x in value] 
  6.         square_list = [x * x for x invalue_list]main() 

這段代碼中,value_list完全沒有必要,這會創建不必要的數據結構或復制。

  1. def main(): 
  2.     size = 10000 
  3.     for _ in range(size): 
  4.         value = range(size) 
  5.         square_list = [x * x for x invalue]main() 

另一個原因在于Python的數據共享機制過于偏執,沒有很好理解或信任內存模型,例如濫用copy.deepcopy()函數。我們可以刪除此類代碼中的復制操作。

交換值時無需使用中間變量

  1. def main(): 
  2.     size = 1000000 
  3.     for _ in range(size): 
  4.         a = 3 
  5.         b = 5 
  6.         temp = a 
  7.         a = b 
  8.         b = tempmain() 

上述代碼在交換值時創建了一個臨時變量temp。如果沒有中間變量,代碼會更加簡潔,運行速度也更快。

  1. def main(): 
  2.     size = 1000000 
  3.     for _ in range(size): 
  4.         a = 3 
  5.         b = 5 
  6.         a, bb = b, amain() 

使用字符串聯方法join ,而不是'+'

  1. import string 
  2. from typing import Listdef concatString(string_list: List[str]) -> str: 
  3.     result = '' 
  4.     for str_i in string_list: 
  5.         result += str_i 
  6.     return resultdef main(): 
  7.     string_list =list(string.ascii_letters * 100) 
  8.     for _ in range(10000): 
  9.         result =concatString(string_list)main() 

另一要點是a+b對字符串進行拼接,由于在Python中字符串是不可變的對象,所以實際上a和b分別復制到了應用程序的新內存空間中。

因此,如果拼接n個字符串會產生“ n-1”個中間結果,則每個字符串都會產生應用和復制內存所需的中間結果,從而嚴重影響操作效率。

在使用join()串聯字符串時,首先計算需要應用的總內存空間,然后立即申請所需的內存,再把每個字符串元素復制到內存中。

  1. import string 
  2. from typing import Listdef concatString(string_list: List[str]) -> str: 
  3.     return ''.join(string_list)defmain(): 
  4.     string_list = list(string.ascii_letters* 100) 
  5.     for _ in range(10000): 
  6.         result =concatString(string_list)main() 

3. 避免使用以下函數屬性

避免訪問模塊和函數屬性

  1. import mathdef computeSqrt(size:int): 
  2.     result = [] 
  3.     for i in range(size): 
  4.         result.append(math.sqrt(i)) 
  5.     return resultdef main(): 
  6.     size = 10000 
  7.     for _ in range(size): 
  8.         result = computeSqrt(size)main() 

use(屬性訪問運算符)會觸發特定方法,例如getattribute()和getattr(),這些方法將執行字典操作,會產生額外的時間消耗。

通過使用import語句,可以消除屬性訪問:

  1. from math import sqrtdefcomputeSqrt(size: int): 
  2.     result = [] 
  3.     for i in range(size): 
  4.         result.append(sqrt(i)) 
  5.     return resultdef main(): 
  6.     size = 10000 
  7.     for _ in range(size): 
  8.         result = computeSqrt(size)main() 

前文中我們討論了局部變量可以比全局變量實現更快查找,對于經常訪問的變量(如sqrt),可以通過更改為局部變量以加快操作速度。

  1. import mathdef computeSqrt(size:int): 
  2.     result = [] 
  3.     sqrt = math.sqrt 
  4.     for i in range(size): 
  5.         result.append(sqrt(i)) 
  6.     return resultdef main(): 
  7.     size = 10000 
  8.     for _ in range(size): 
  9.         result = computeSqrt(size)main() 

避免類屬性訪問

  1. import math 
  2. from typing import Listclass DemoClass: 
  3.     def __init__(self, value: int): 
  4.         self._value = value 
  5.     
  6.     def computeSqrt(self, size: int)-> List[float]: 
  7.         result = [] 
  8.         append = result.append 
  9.         sqrt = math.sqrt 
  10.         for _ in range(size): 
  11.             append(sqrt(self._value)) 
  12.         return resultdef main(): 
  13.     size = 10000 
  14.     for _ in range(size): 
  15.         demo_instance = DemoClass(size) 
  16.         result =demo_instance.computeSqrt(size)main() 

避免的原理也適用于類的屬性,并且訪問self._value的速度要比訪問局部變量的速度要慢。通過把需要頻繁訪問的類屬性分配給局部變量,可以提高代碼執行速度。

  1. import math 
  2. from typing import Listclass DemoClass: 
  3.     def __init__(self, value: int): 
  4.         self._value = value 
  5.     
  6.     def computeSqrt(self, size: int)-> List[float]: 
  7.         result = [] 
  8.         append = result.append 
  9.         sqrt = math.sqrt 
  10.         value = self._value 
  11.         for _ in range(size): 
  12.             append(sqrt(value)) 
  13.         return resultdef main(): 
  14.     size = 10000 
  15.     for _ in range(size): 
  16.         demo_instance = DemoClass(size) 
  17.        demo_instance.computeSqrt(size)main() 

4. 避免不必要的抽象

  1. class DemoClass: 
  2.     def __init__(self, value: int): 
  3.         self.value = value@property 
  4.     def value(self) -> int: 
  5.         return self._value@value.setter 
  6.     def value(self, x: int): 
  7.         self._value = xdef main(): 
  8.     size = 1000000 
  9.     for i in range(size): 
  10.         demo_instance = DemoClass(size) 
  11.         value = demo_instance.value 
  12.         demo_instance.value = imain() 

每當使用其他處理層(例如裝飾器、屬性訪問、描述符)封裝代碼時,代碼運行的速度也會變慢。在大多數情況下,重新檢查是否有必要使用屬性訪問器定義是很有必要的。

使用getter/setter函數訪問屬性通常是被C/C++程序員遺忘的一種編碼樣式。如果確實沒有必要,就使用簡單屬性就好。

  1. class DemoClass: 
  2.     def __init__(self, value: int): 
  3.         self.value = valuedef main(): 
  4.     size = 1000000 
  5.     for i in range(size): 
  6.         demo_instance = DemoClass(size) 
  7.         value = demo_instance.value 
  8.         demo_instance.value = imain() 

5. 選擇合適的數據結構

眾所周知,列表是Python中的動態數組。當預分配的內存空間用完時,會預分配一定的內存空間,然后繼續向其中添加元素。然后復制之前的所有原始元素,形成一個新的內存空間,在插入新元素之前銷毀先前的內存空間。

因此,如果頻繁添加或刪除,或者添加或刪除的元素數量太大,列表的效率就會變低,目前最好使用collections.deque。

此雙端隊列具有堆棧和隊列的特性,并且可以在兩端以O(1)復雜度執行插入和刪除操作。

列表搜索操作非常耗時。當需要頻繁查找某些元素或按順序頻繁訪問這些元素時,保持列表 對象有序的情況下使用二分法,使用二進制搜索以提高搜索效率,但二進制搜索僅適用于有序元素。

另一個常見的要求是找到最小值或最大值。此時,可以使用heapq模塊列出轉換為堆的列表,因此獲取最小值的時間復雜度為O(1)。

6. 循環優化

使用 for 循環代替while 循環

  1. def computeSum(size: int) ->int: 
  2.     sum_ = 0 
  3.     i = 0 
  4.     while i < size: 
  5.         sum_ += i 
  6.         i += 1 
  7.     return sum_def main(): 
  8.     size = 10000 
  9.     for _ in range(size): 
  10.         sum_ = computeSum(size)main() 

要知道,Python中的for循環要比while循環快得多。

  1. def computeSum(size: int) ->int: 
  2.     sum_ = 0 
  3.     for i in range(size): 
  4.         sum_ += i 
  5.     return sum_def main(): 
  6.     size = 10000 
  7.     for _ in range(size): 
  8.         sum_ = computeSum(size)main() 

使用隱式for循環,而不是顯式for循環

對于上面的示例,可以進一步使用隱式for循環替換顯式for循環

  1. def computeSum(size: int) ->int: 
  2.     return sum(range(size))def main(): 
  3.     size = 10000 
  4.     for _ in range(size): 
  5.         sum = computeSum(size)main() 

減少內部循環的計算

  1. from math import sqrtdef main(): 
  2.     size = 10000    for x in range(size): 
  3.         for y in range(size): 
  4.             z = sqrt(x) + sqrt(y)main() 

在上述for循環中的代碼sqrt(x)中,在訓練期間每次都需要進行重新計算,這會增加時間消耗。

  1. import mathdef main(): 
  2.     size = 10000for x in range(size): 
  3.         sqrtsqrt_x = sqrt(x) 
  4.         for y in range(size): 
  5.             z = sqrt_x + sqrt(y)main() 

7. 使用 numba.jit

繼續遵循上述示例,并在此基礎上使用numba.jit。Python函數JIT可以編譯為機器代碼用以執行,這能大大提高了代碼執行速度。

  1. import numba@numba.jit 
  2. def computeSum(size: float) -> int: 
  3.     sum = 0 
  4.     for i in range(size): 
  5.         sum += i 
  6.     return sumdef main(): 
  7.     size = 10000 
  8.     for _ in range(size): 
  9.         sum = computeSum(size)main() 

8. 代碼優化原則

上文已經介紹了許多加速Python代碼的技術。在編寫代碼的過程中,我們需要了解代碼優化的一些基本原理,這可是“實用知識”。

第一個基本原則就是不要過早優化代碼。

許多人一開始編寫代碼時就致力于性能優化,“加快正確程序的速度要比確保快速程序的正確運作容易得多。”優化代碼的前提是確保代碼可以正常工作。過早的優化可能會忽略對總體性能指標的掌握,并且在獲得總體結果之前不要顛倒順序。

第二個基本原則是權衡優化代碼的成本。

優化代碼是有代價的,想要解決所有性能問題幾乎不可能。通常面臨的選擇是時間換空間或空間換時間,還需要考慮開發成本。

第三個原則是不要優化無關緊要的部分。

如果優化代碼的每個部分后,這些變更會讓代碼變得難以閱讀和理解。如果代碼運行緩慢,首先必須找到代碼運行緩慢的位置(通常是內部循環),重點優化代碼運行緩慢的地方。對于其他位置,時間的損失影響很小。

優化代碼,讓你的Python開足馬力,快去實踐一下吧!

 

責任編輯:趙寧寧 來源: 今日頭條
相關推薦

2013-03-25 09:41:20

PythonCython

2019-03-25 21:18:41

數據科學家大數據技能

2020-07-23 14:15:42

Cython的Python代碼

2024-12-03 00:38:37

數據湖存儲COS

2009-06-29 10:34:49

網站加速Page SpeedGoogle

2020-06-15 14:43:16

Python開發工具

2021-03-18 07:52:42

代碼性能技巧開發

2021-07-05 09:40:57

工具Node開源

2020-06-22 15:41:20

IF函數Excel用法

2017-10-18 09:49:57

ERP信息化CIO

2024-08-09 11:07:46

緩存檢索filter

2011-01-13 14:38:00

JavascriptCSSWeb

2022-05-29 08:54:44

Edge瀏覽器

2018-03-19 08:30:02

編程開發技能

2023-06-08 11:23:56

數字化轉型企業

2018-08-14 08:14:27

安卓Google特性

2017-01-18 10:18:54

微軟

2020-05-25 18:42:52

Windows 10Windows操作系統

2011-11-02 17:03:34

Vmware云計算

2022-08-01 08:12:14

位運算代碼性能
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美精品久久一区 | 精品欧美一区二区三区久久久 | 日韩欧美大片在线观看 | 91久久精品国产91久久 | 男女网站免费 | 日韩毛片播放 | 国产精品污www一区二区三区 | 亚洲国产日本 | 久草中文在线 | 99久久久久久99国产精品免 | 欧美日韩高清在线一区 | 精品99爱视频在线观看 | 久草资源在线视频 | 黄片毛片免费看 | 欧美jizzhd精品欧美巨大免费 | 欧美99 | 亚洲天堂中文字幕 | 国产精品日日摸夜夜添夜夜av | 国产精品一区在线 | 日本福利一区 | 色噜噜亚洲男人的天堂 | 亚洲精品视频在线 | 亚洲色欧美另类 | 国产欧美一区二区三区免费 | 欧美精品久久久久久 | 成人国产在线观看 | 国产午夜一级 | 91中文字幕在线观看 | 国产91综合 | a黄视频| 精品自拍视频在线观看 | 成人欧美一区二区三区视频xxx | 99亚洲精品 | 99只有精品| 国产精品免费一区二区 | 久草热视频 | h视频在线观看免费 | 亚洲欧美日韩精品久久亚洲区 | 国产精品久久精品 | 国产免费一区二区 | 伊人在线|