有哪些Python加速技能

這篇文章主要講解了“有哪些Python加速技能”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“有哪些Python加速技能”吧!

成都創(chuàng)新互聯(lián)公司網(wǎng)站建設(shè)公司,提供成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè),網(wǎng)頁設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);可快速的進行網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,是專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!

1. 避免使用全局變量

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

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

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

import mathdef main():     size = 10000     for x in range(size):         for y in range(size):             z = math.sqrt(x) +math.sqrt(y)main()

2. 避免數(shù)據(jù)重復(fù)

避免無意義的數(shù)據(jù)復(fù)制

def main():     size = 10000     for _ in range(size):         value = range(size)         value_list = [x for x in value]         square_list = [x * x for x invalue_list]main()

這段代碼中,value_list完全沒有必要,這會創(chuàng)建不必要的數(shù)據(jù)結(jié)構(gòu)或復(fù)制。

def main():     size = 10000     for _ in range(size):         value = range(size)         square_list = [x * x for x invalue]main()

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

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

def main():     size = 1000000     for _ in range(size):         a = 3         b = 5         temp = a         a = b         b = tempmain()

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

def main():     size = 1000000     for _ in range(size):         a = 3         b = 5         a, bb = b, amain()

使用字符串聯(lián)方法join ,而不是'+'

import string from typing import Listdef concatString(string_list: List[str]) -> str:     result = ''     for str_i in string_list:         result += str_i     return resultdef main():     string_list =list(string.ascii_letters * 100)     for _ in range(10000):         result =concatString(string_list)main()

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

因此,如果拼接n個字符串會產(chǎn)生“ n-1”個中間結(jié)果,則每個字符串都會產(chǎn)生應(yīng)用和復(fù)制內(nèi)存所需的中間結(jié)果,從而嚴重影響操作效率。

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

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

3. 避免使用以下函數(shù)屬性

避免訪問模塊和函數(shù)屬性

import mathdef computeSqrt(size:int):     result = []     for i in range(size):         result.append(math.sqrt(i))     return resultdef main():     size = 10000     for _ in range(size):         result = computeSqrt(size)main()

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

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

from math import sqrtdefcomputeSqrt(size: int):     result = []     for i in range(size):         result.append(sqrt(i))     return resultdef main():     size = 10000     for _ in range(size):         result = computeSqrt(size)main()

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

import mathdef computeSqrt(size:int):     result = []     sqrt = math.sqrt     for i in range(size):         result.append(sqrt(i))     return resultdef main():     size = 10000     for _ in range(size):         result = computeSqrt(size)main()

避免類屬性訪問

import math from typing import Listclass DemoClass:     def __init__(self, value: int):         self._value = value         def computeSqrt(self, size: int)-> List[float]:         result = []         append = result.append         sqrt = math.sqrt         for _ in range(size):             append(sqrt(self._value))         return resultdef main():     size = 10000     for _ in range(size):         demo_instance = DemoClass(size)         result =demo_instance.computeSqrt(size)main()

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

import math from typing import Listclass DemoClass:     def __init__(self, value: int):         self._value = value         def computeSqrt(self, size: int)-> List[float]:         result = []         append = result.append         sqrt = math.sqrt         value = self._value         for _ in range(size):             append(sqrt(value))         return resultdef main():     size = 10000     for _ in range(size):         demo_instance = DemoClass(size)        demo_instance.computeSqrt(size)main()

4. 避免不必要的抽象

class DemoClass:     def __init__(self, value: int):         self.value = value@property     def value(self) -> int:         return self._value@value.setter     def value(self, x: int):         self._value = xdef main():     size = 1000000     for i in range(size):         demo_instance = DemoClass(size)         value = demo_instance.value         demo_instance.value = imain()

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

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

class DemoClass:     def __init__(self, value: int):         self.value = valuedef main():     size = 1000000     for i in range(size):         demo_instance = DemoClass(size)         value = demo_instance.value         demo_instance.value = imain()

5. 選擇合適的數(shù)據(jù)結(jié)構(gòu)

眾所周知,列表是Python中的動態(tài)數(shù)組。當(dāng)預(yù)分配的內(nèi)存空間用完時,會預(yù)分配一定的內(nèi)存空間,然后繼續(xù)向其中添加元素。然后復(fù)制之前的所有原始元素,形成一個新的內(nèi)存空間,在插入新元素之前銷毀先前的內(nèi)存空間。

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

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

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

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

6. 循環(huán)優(yōu)化

使用 for 循環(huán)代替while 循環(huán)

def computeSum(size: int) ->int:     sum_ = 0     i = 0     while i < size:         sum_ += i         i += 1     return sum_def main():     size = 10000     for _ in range(size):         sum_ = computeSum(size)main()

要知道,Python中的for循環(huán)要比while循環(huán)快得多。

def computeSum(size: int) ->int:     sum_ = 0     for i in range(size):         sum_ += i     return sum_def main():     size = 10000     for _ in range(size):         sum_ = computeSum(size)main()

使用隱式for循環(huán),而不是顯式for循環(huán)

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

def computeSum(size: int) ->int:     return sum(range(size))def main():     size = 10000     for _ in range(size):         sum = computeSum(size)main()

減少內(nèi)部循環(huán)的計算

from math import sqrtdef main():     size = 10000    for x in range(size):         for y in range(size):             z = sqrt(x) + sqrt(y)main()

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

import mathdef main():     size = 10000for x in range(size):         sqrtsqrt_x = sqrt(x)         for y in range(size):             z = sqrt_x + sqrt(y)main()

7. 使用 numba.jit

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

import numba@numba.jit def computeSum(size: float) -> int:     sum = 0     for i in range(size):         sum += i     return sumdef main():     size = 10000     for _ in range(size):         sum = computeSum(size)main()

8. 代碼優(yōu)化原則

第一個基本原則就是不要過早優(yōu)化代碼。

許多人一開始編寫代碼時就致力于性能優(yōu)化,“加快正確程序的速度要比確??焖俪绦虻恼_運作容易得多?!眱?yōu)化代碼的前提是確保代碼可以正常工作。過早的優(yōu)化可能會忽略對總體性能指標的掌握,并且在獲得總體結(jié)果之前不要顛倒順序。

第二個基本原則是權(quán)衡優(yōu)化代碼的成本。

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

第三個原則是不要優(yōu)化無關(guān)緊要的部分。

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

感謝各位的閱讀,以上就是“有哪些Python加速技能”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對有哪些Python加速技能這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

網(wǎng)頁名稱:有哪些Python加速技能
網(wǎng)站路徑:http://muchs.cn/article8/ghjdop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、品牌網(wǎng)站設(shè)計小程序開發(fā)、云服務(wù)器、網(wǎng)站建設(shè)、電子商務(wù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作