自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

加速 Python 代碼的八個優(yōu)秀實用技巧

開發(fā)
Python在解決復(fù)雜問題時可能會顯得執(zhí)行速度較慢,因此,本文將探討一些優(yōu)化Python代碼的方法,以加速代碼運行。

Python是目前世界上增長最快的編程語言之一,深受全球開發(fā)者的喜愛。其簡單語法和豐富的庫使得在各個領(lǐng)域都能得到廣泛應(yīng)用,比如數(shù)據(jù)科學(xué)、機器學(xué)習(xí)、信號處理、數(shù)據(jù)可視化等。然而,Python在解決復(fù)雜問題時可能會顯得執(zhí)行速度較慢。因此,本文將探討一些優(yōu)化Python代碼的方法,以加速代碼運行。

1.使用內(nèi)置函數(shù)和庫

Python標(biāo)準(zhǔn)庫和第三方庫(如NumPy、Pandas等)中的函數(shù)通常是用C或Cython編寫的,運行速度遠超純Python代碼。為了加速Python代碼,可以盡量使用這些庫中的向量化操作代替Python原生循環(huán),特別是在處理數(shù)組和矩陣運算時。

舉個例子,計算Python列表中每個元素的平方。

import numpy as np
import time

# 定義一個Python列表
python_list = [1, 2, 3, 4, 5]

# 使用純Python循環(huán)計算平方的時間測試
def measure_time(function, argument):
    start_time = time.time()
    result = function(argument)
    end_time = time.time()
    return result, end_time - start_time

# 定義純Python循環(huán)計算平方的函數(shù)
def square_elements_python(lst):
    squared_lst = []
    for num in lst:
        squared_lst.append(num ** 2)
    return squared_lst

# 計算并輸出純Python循環(huán)方法執(zhí)行時間和結(jié)果
python_squares, python_time = measure_time(square_elements_python, python_list)
print(f"純Python循環(huán)方法: {python_squares}, Time taken: {python_time} seconds")

# 轉(zhuǎn)換為NumPy數(shù)組并使用向量化操作
start_time = time.time()
numpy_array = np.array(python_list)
numpy_squares = numpy_array ** 2
end_time = time.time()

# 輸出NumPy向量化操作執(zhí)行時間
numpy_time = end_time - start_time
print(f"NumPy向量化操作: {numpy_squares.tolist()}, Time taken: {numpy_time} seconds")

輸出結(jié)果如下,由此可以看出NumPy的向量化操作在執(zhí)行速度上遠超純Python循環(huán)法。這是因為NumPy內(nèi)部對數(shù)組操作進行了高度優(yōu)化,并利用C語言編寫的底層算法,極大地提高了處理效率。

純Python循環(huán)方法: [1, 4, 9, 16, 25], Time taken: 4.5299530029296875e-06 seconds
NumPy向量化操作: [1, 4, 9, 16, 25], Time taken: 0.00020122528076171875 seconds

2.Numba JIT編譯

可以使用Numba庫進行即時(JIT)編譯,它可以將指定的Python函數(shù)轉(zhuǎn)換為高效機器碼,以提升執(zhí)行速度。尤其適用于數(shù)值計算密集型代碼。

例如下面的代碼,sum_array函數(shù)被裝飾器@jit(nopython=True)標(biāo)記后,Numba會對其進行即時編譯,將其轉(zhuǎn)換為機器碼以提升計算密集型任務(wù)的執(zhí)行速度。

import numpy as np
from numba import jit

@jit(nopython=True)
def sum_array(arr: np.ndarray) -> float:
    result = 0.0
    for i in range(arr.shape[0]):
        result += arr[i]
    return result

arr = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
print(sum_array(arr))

3.避免不必要的copy操作

盡可能在原地修改對象,而不是創(chuàng)建新對象。例如,使用列表的extend()方法而非"+"操作符進行合并,使用numpy數(shù)組的切片賦值而不是重新創(chuàng)建數(shù)組。例如:

# 避免:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
new_list = list1 + list2

# 推薦:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
# 這里不會創(chuàng)建新的列表對象,而是直接在原地擴展list1
list1.extend(list2)

4.使用生成器表達式代替列表推導(dǎo)

當(dāng)不需要一次性生成所有結(jié)果,而是逐個處理時,使用生成器表達式代替列表推導(dǎo)式可以節(jié)省內(nèi)存,因為它不會立即創(chuàng)建完整列表。

例如假設(shè)有一個包含整數(shù)的列表,我們想要計算每個整數(shù)的平方并輸出結(jié)果。使用列表推導(dǎo)式的方法如下:

numbers = [1, 2, 3, 4, 5]
squared_numbers = [num ** 2 for num in numbers]
for squared_num in squared_numbers:
    print(squared_num)

輸出結(jié)果為:

1
4
9
16
25

但是,如果我們只需要逐個處理每個平方數(shù),而不需要將它們存儲在內(nèi)存中,可以使用生成器表達式代替列表推導(dǎo)式:

numbers = [1, 2, 3, 4, 5]
squared_numbers = (num ** 2 for num in numbers)
for squared_num in squared_numbers:
    print(squared_num)

輸出結(jié)果與之前相同,但是使用生成器表達式可以節(jié)省內(nèi)存,因為它不會一次性生成所有結(jié)果,而是逐個生成。

5.合理利用多線程或多進程

對于CPU密集型任務(wù),Python的多線程受GIL限制,但對于IO密集型任務(wù)或是使用多核CPU處理CPU密集型任務(wù)時,可以通過multiprocessing庫開啟多進程來提升效率。

例如如下代碼定義了一個計算密集型函數(shù)cpu_bound_task,然后通過multiprocessing.Pool創(chuàng)建了與CPU核心數(shù)量相等的進程池,并用pool.map()方法將輸入列表中的任務(wù)分配給這些進程進行并行處理。

這樣,每個進程都有自己的內(nèi)存空間和獨立GIL,從而可以充分利用多核處理器的能力提高執(zhí)行效率。

import multiprocessing as mp

def cpu_bound_task(n):
    # 模擬的CPU密集型計算任務(wù)
    result = 0
    for i in range(n):
        result += i * i
    return result

if __name__ == "__main__":
    inputs = [1_000_000 + x for x in range(10)]  # 多個需要處理的數(shù)據(jù)單元

    with mp.Pool(processes=mp.cpu_count()) as pool:  # 使用所有可用CPU核心數(shù)
        results = pool.map(cpu_bound_task, inputs)  # 將任務(wù)分配到各個進程中并行處理

    print(f"Results: {results}")

6.緩存計算結(jié)果

如果存在重復(fù)計算的情況,可以使用functools.lru_cache裝飾器來緩存函數(shù)的返回結(jié)果,避免重復(fù)計算。

如下示例使用Python標(biāo)準(zhǔn)庫中的functools.lru_cache裝飾器來緩存函數(shù)的結(jié)果,避免重復(fù)計算。

from functools import lru_cache

@lru_cache(maxsize=None)  # 緩存所有結(jié)果,可以根據(jù)實際情況設(shè)置緩存大小
def expensive_computation(x):
    # 假設(shè)這是一個計算成本很高的函數(shù)
    print("Computing...")
    return x ** x

# 第一次調(diào)用時會執(zhí)行計算
result1 = expensive_computation(5)
# 第二次調(diào)用時會從緩存中獲取結(jié)果,不再執(zhí)行計算
result2 = expensive_computation(5)
print(result1 == result2)

第一次調(diào)用expensive_computation(5)時,執(zhí)行計算并打印"Computing...",然后返回計算結(jié)果25。第二次調(diào)用時,由于結(jié)果已被緩存,不再執(zhí)行計算,直接返回上次計算得到的25。因此,result1 == result2的輸出是True。

7.利用異步IO

在處理大量IO操作時,如網(wǎng)絡(luò)請求、文件讀寫等,可以利用asyncio庫實現(xiàn)異步編程,最大化利用等待IO完成的時間進行其他任務(wù)的處理。

例如下面例子使用Python的asyncio庫來并行處理多個網(wǎng)絡(luò)請求,它會同時發(fā)起10個對'

8.使用Cython或者Python-C接口

對于計算密集型的部分代碼,可以使用Cython編寫,將其編譯為C擴展模塊,或者直接使用Python的C API編寫擴展模塊,這種方式可以大幅提高這部分代碼的執(zhí)行效率。示例如下:

首先,安裝Cython并創(chuàng)建.pyx文件:

然后,編譯為C擴展模塊:

最后,在Python中導(dǎo)入并使用:

通過這種方法,Cython能夠自動將Python代碼轉(zhuǎn)化為C代碼,使得原本在Python中執(zhí)行的某些計算密集型任務(wù)得以顯著加速。

責(zé)任編輯:趙寧寧 來源: 小喵學(xué)AI
相關(guān)推薦

2023-11-28 12:07:06

Python代碼

2021-12-11 23:13:16

Python語言技巧

2022-03-18 21:27:36

Python無代碼

2024-11-26 14:18:44

Python代碼技巧

2010-09-01 13:55:14

CSS

2023-01-11 11:35:40

重構(gòu)PythonPythonic

2023-09-26 12:04:15

重構(gòu)技巧Pythonic

2023-02-06 12:00:00

重構(gòu)PythonPythonic

2022-12-01 16:53:27

NPM技巧

2024-05-22 09:29:43

2025-04-03 08:27:00

Python代碼開發(fā)

2012-10-29 11:01:17

2024-08-27 12:18:23

函數(shù)Python

2024-12-27 08:43:17

2021-11-15 10:02:16

Python命令技巧

2023-04-26 00:34:36

Python技巧程序員

2024-09-11 16:30:55

Python函數(shù)編程

2023-10-10 10:27:37

DevOps

2022-06-13 09:00:33

React 項目前端

2022-12-15 16:38:17

點贊
收藏

51CTO技術(shù)棧公眾號