最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

讓Python代碼運(yùn)行更快的9個(gè)小技巧

 更新時(shí)間:2024年01月09日 10:12:43   作者:咸魚運(yùn)維雜談  
我們經(jīng)常聽到 “Python 太慢了”,“Python 性能不行”這樣的觀點(diǎn),但是,只要掌握一些編程技巧,就能大幅提升 Python 的運(yùn)行速度,今天就讓我們一起來看下讓 Python 性能更高的 9 個(gè)小技巧,需要的朋友可以參考下

字符串拼接的技巧

如果有大量字符串等待處理,字符串連接將成為 Python 的瓶頸。

一般來講,Python 中有兩種字符串拼接方式:

  • 使用該 join() 函數(shù)將字符串列表合并為一個(gè)字符串
  • 使用 + or += 符號(hào)將每個(gè)字符串加成一個(gè)

那么哪種方式更快呢?我們一起來看一下

mylist = ["Yang", "Zhou", "is", "writing"]
?
?
# Using '+'
def concat_plus():
    result = ""
    for word in mylist:
        result += word + " "
    return result
?
?
# Using 'join()'
def concat_join():
    return " ".join(mylist)
?
?
# Directly concatenation without the list
def concat_directly():
    return "Yang" + "Zhou" + "is" + "writing"
import timeit
?
print(timeit.timeit(concat_plus, number=10000))
# 0.002738415962085128
print(timeit.timeit(concat_join, number=10000))
# 0.0008482920238748193
print(timeit.timeit(concat_directly, number=10000))
# 0.00021425005979835987

如上所示,對于拼接字符串列表, join() 方法比在 for 循環(huán)中逐個(gè)添加字符串更快。

原因很簡單。一方面,字符串是 Python 中的不可變數(shù)據(jù),每個(gè) += 操作都會(huì)導(dǎo)致創(chuàng)建一個(gè)新字符串并復(fù)制舊字符串,這會(huì)導(dǎo)致非常大的開銷。

另一方面,.join() 方法是專門為連接字符串序列而優(yōu)化的。它預(yù)先計(jì)算結(jié)果字符串的大小,然后一次性構(gòu)建它。因此,它避免了與循環(huán)中 += 操作相關(guān)的開銷,因此速度更快。

但是,我們發(fā)現(xiàn)最快其實(shí)是直接用 + 拼接字符串,這是因?yàn)椋?/p>

  • Python 解釋器可以在編譯時(shí)優(yōu)化字符串的連接,將它們轉(zhuǎn)換為單個(gè)字符串。因?yàn)闆]有循環(huán)迭代或函數(shù)調(diào)用,所以它是一個(gè)非常高效的操作。
  • 由于所有字符串在編譯時(shí)都是已知的,因此 Python 可以非??焖俚貓?zhí)行此操作,比循環(huán)中的運(yùn)行時(shí)連接甚至優(yōu)化 .join() 方法快得多。

總之,如果需要拼接字符串列表,請選擇 join() ;如果直接拼接字符串,只需使用 + 即可。

創(chuàng)建列表的技巧

Python 中創(chuàng)建列表的兩種常見方法是:

  • 使用函數(shù) list()
  • [] 直接使用

我們來看下這兩種方法的性能

import timeit
?
print(timeit.timeit('[]', number=10 ** 7))
# 0.1368238340364769
print(timeit.timeit(list, number=10 ** 7))
# 0.2958830420393497

結(jié)果表明,執(zhí)行 list() 函數(shù)比直接使用 [] 要慢。

這是因?yàn)?是 [] 字面語法( literal syntax ),而 list() 是構(gòu)造函數(shù)調(diào)用。毫無疑問,調(diào)用函數(shù)需要額外的時(shí)間。

同理,在創(chuàng)建字典時(shí),我們也應(yīng)該利用 {} 而不是 dict()

成員關(guān)系測試的技巧

成員關(guān)系測試的性能很大程度上取決于底層數(shù)據(jù)結(jié)構(gòu)

import timeit
?
large_dataset = range(100000)
search_element = 2077
?
large_list = list(large_dataset)
large_set = set(large_dataset)
?
?
def list_membership_test():
    return search_element in large_list
?
?
def set_membership_test():
    return search_element in large_set
?
?
print(timeit.timeit(list_membership_test, number=1000))
# 0.01112208398990333
print(timeit.timeit(set_membership_test, number=1000))
# 3.27499583363533e-05

如上面的代碼所示,集合中的成員關(guān)系測試比列表中的成員關(guān)系測試要快得多。

這是為什么呢?

  • 在 Python 列表中,成員關(guān)系測試 ( element in list ) 是通過遍歷每個(gè)元素來完成的,直到找到所需的元素或到達(dá)列表的末尾。因此,此操作的時(shí)間復(fù)雜度為 O(n)。
  • Python 中的集合是作為哈希表實(shí)現(xiàn)的。在檢查成員資格 ( element in set ) 時(shí),Python 使用哈希機(jī)制,其時(shí)間復(fù)雜度平均為 O(1)。

這里的技巧重點(diǎn)是在編寫程序時(shí)仔細(xì)考慮底層數(shù)據(jù)結(jié)構(gòu)。利用正確的數(shù)據(jù)結(jié)構(gòu)可以顯著加快我們的代碼速度。

使用推導(dǎo)式而不是 for 循環(huán)

Python 中有四種類型的推導(dǎo)式:列表、字典、集合和生成器。它們不僅為創(chuàng)建相對數(shù)據(jù)結(jié)構(gòu)提供了更簡潔的語法,而且比使用 for 循環(huán)具有更好的性能。

因?yàn)樗鼈冊?Python 的 C 實(shí)現(xiàn)中進(jìn)行了優(yōu)化。

import timeit
?
?
def generate_squares_for_loop():
    squares = []
    for i in range(1000):
        squares.append(i * i)
    return squares
?
?
def generate_squares_comprehension():
    return [i * i for i in range(1000)]
?
?
print(timeit.timeit(generate_squares_for_loop, number=10000))
# 0.2797503340989351
print(timeit.timeit(generate_squares_comprehension, number=10000))
# 0.2364629579242319

上面的代碼是列表推導(dǎo)式和 for 循環(huán)之間的簡單速度比較。如結(jié)果所示,列表推導(dǎo)式速度更快。

訪問局部變量速度更快

在 Python 中,訪問局部變量比訪問全局變量或?qū)ο蟮膶傩愿臁?/p>

import timeit
?
?
class Example:
    def __init__(self):
        self.value = 0
?
?
obj = Example()
?
?
def test_dot_notation():
    for _ in range(1000):
        obj.value += 1
?
?
def test_local_variable():
    value = obj.value
    for _ in range(1000):
        value += 1
    obj.value = value
?
?
print(timeit.timeit(test_dot_notation, number=1000))
# 0.036605041939765215
print(timeit.timeit(test_local_variable, number=1000))
# 0.024470250005833805

原理也很簡單:當(dāng)編譯一個(gè)函數(shù)時(shí),它內(nèi)部的局部變量是已知的,但其他外部變量需要時(shí)間來檢索。

優(yōu)先考慮內(nèi)置模塊和庫

當(dāng)我們討論 Python 的時(shí)候,通常指的是 CPython,因?yàn)?CPython 是 Python 語言的默認(rèn)和使用最廣泛的實(shí)現(xiàn)。

考慮到它的大多數(shù)內(nèi)置模塊和庫都是用C語言編寫的,C語言是一種更快、更低級(jí)的語言,我們應(yīng)該利用它的內(nèi)置庫,避免重復(fù)造輪子。

import timeit
import random
from collections import Counter
?
?
def count_frequency_custom(lst):
    frequency = {}
    for item in lst:
        if item in frequency:
            frequency[item] += 1
        else:
            frequency[item] = 1
    return frequency
?
?
def count_frequency_builtin(lst):
    return Counter(lst)
?
?
large_list = [random.randint(0, 100) for _ in range(1000)]
?
print(timeit.timeit(lambda: count_frequency_custom(large_list), number=100))
# 0.005160166998393834
print(timeit.timeit(lambda: count_frequency_builtin(large_list), number=100))
# 0.002444291952997446

上面的程序比較了計(jì)算列表中元素頻率的兩種方法。正如我們所看到的,利用 collections 模塊的內(nèi)置計(jì)數(shù)器比我們自己編寫 for 循環(huán)更快、更簡潔、更好。

使用緩存裝飾器

緩存是避免重復(fù)計(jì)算和提高程序速度的常用技術(shù)。

幸運(yùn)的是,在大多數(shù)情況下,我們不需要編寫自己的緩存處理代碼,因?yàn)?Python 提供了一個(gè)開箱即用的裝飾器 — @functools.cache 。

例如,以下代碼將執(zhí)行兩個(gè)斐波那契數(shù)生成函數(shù),一個(gè)具有緩存裝飾器,但另一個(gè)沒有:

import timeit
import functools
?
?
def fibonacci(n):
    if n in (0, 1):
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)
?
?
@functools.cache
def fibonacci_cached(n):
    if n in (0, 1):
        return n
    return fibonacci_cached(n - 1) + fibonacci_cached(n - 2)
?
?
# Test the execution time of each function
print(timeit.timeit(lambda: fibonacci(30), number=1))
# 0.09499712497927248
print(timeit.timeit(lambda: fibonacci_cached(30), number=1))
# 6.458023563027382e-06

可以看到 functools.cache 裝飾器如何使我們的代碼運(yùn)行得更快。

緩存版本的速度明顯更快,因?yàn)樗彺媪讼惹坝?jì)算的結(jié)果。因此,它只計(jì)算每個(gè)斐波那契數(shù)一次,并從緩存中檢索具有相同參數(shù)的后續(xù)調(diào)用

while 1 VS while True

如果要?jiǎng)?chuàng)建無限 while 循環(huán),我們可以使用 while True or while 1 .

它們的性能差異通??梢院雎圆挥?jì)。但有趣的是, while 1 稍微快一點(diǎn)。

這是因?yàn)槭?1 字面量,但 True 是一個(gè)全局名稱,需要在 Python 的全局作用域中查找。所以 1 的開銷很小。

import timeit
?
?
def loop_with_true():
    i = 0
    while True:
        if i >= 1000:
            break
        i += 1
?
?
def loop_with_one():
    i = 0
    while 1:
        if i >= 1000:
            break
        i += 1
?
?
print(timeit.timeit(loop_with_true, number=10000))
# 0.1733035419601947
print(timeit.timeit(loop_with_one, number=10000))
# 0.16412191605195403

正如我們所看到的,確實(shí) while 1 稍微快一些。

然而,現(xiàn)代 Python 解釋器(如 CPython )是高度優(yōu)化的,這種差異通常是微不足道的。所以我們不需要擔(dān)心這個(gè)可以忽略不計(jì)的差異。更不用說 while Truewhile 1 可讀性更好。

按需導(dǎo)入 Python 模塊

在 Python 腳本開頭導(dǎo)入所有模塊似乎是每個(gè)人都會(huì)這么做的操作,事實(shí)上我們沒有必要導(dǎo)入全部的模塊。如果模塊太大,則根據(jù)需要導(dǎo)入它是一個(gè)更好的主意。

def my_function():
    import heavy_module
    # rest of the function

如上面的代碼所示,heavy_module 在函數(shù)中導(dǎo)入。這是一種“延遲加載”的思想:只有 my_function 被調(diào)用的時(shí)候該模塊才會(huì)被導(dǎo)入。

這種方法的好處是,如果 my_function 在腳本執(zhí)行期間從未調(diào)用過,則 heavy_module 永遠(yuǎn)不會(huì)加載,從而節(jié)省資源并減少腳本的啟動(dòng)時(shí)間。

以上就是讓Python代碼運(yùn)行更快的9個(gè)小技巧的詳細(xì)內(nèi)容,更多關(guān)于Python代碼運(yùn)行的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • PyCharm+Pipenv虛擬環(huán)境開發(fā)和依賴管理的教程詳解

    PyCharm+Pipenv虛擬環(huán)境開發(fā)和依賴管理的教程詳解

    這篇文章主要介紹了PyCharm+Pipenv虛擬環(huán)境作開發(fā)和依賴管理的教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • python把1變成01的步驟總結(jié)

    python把1變成01的步驟總結(jié)

    在本文里我們給學(xué)習(xí)python的朋友們整理了關(guān)于python把1變成01的步驟總結(jié)內(nèi)容,有需要的朋友們學(xué)習(xí)下。
    2019-02-02
  • Python制作動(dòng)態(tài)字符畫的源碼

    Python制作動(dòng)態(tài)字符畫的源碼

    python字符畫是一個(gè)簡單有趣的圖畫,它一般由程序制作而成,接下來通過本文給大家分享Python制作動(dòng)態(tài)字符畫的源碼,需要的朋友可以參考下
    2021-08-08
  • Python利用xlrd和xlwt模塊進(jìn)行自動(dòng)化操作讀寫Excel的完整指南

    Python利用xlrd和xlwt模塊進(jìn)行自動(dòng)化操作讀寫Excel的完整指南

    在日常工作中,Excel表格是不可或缺的數(shù)據(jù)處理工具,本文將介紹xlrd和xlwt模塊的參數(shù)說明,并通過代碼實(shí)戰(zhàn)演示如何進(jìn)行Excel的讀寫操作,有需要的可以了解下
    2025-11-11
  • Python合并兩個(gè)Excel文件的兩種主流方法

    Python合并兩個(gè)Excel文件的兩種主流方法

    在日常數(shù)據(jù)處理中,合并Excel文件是常見需求,Python提供了多種庫(如pandas、openpyxl)來實(shí)現(xiàn)這一操作,本文將詳細(xì)介紹兩種主流方法,并附上完整代碼示例,幫助您高效完成Excel合并任務(wù),需要的朋友可以參考下
    2025-08-08
  • python playwright之元素定位示例詳解

    python playwright之元素定位示例詳解

    這篇文章主要為大家介紹了python playwright之元素定位示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • python中waitKey實(shí)例用法講解

    python中waitKey實(shí)例用法講解

    在本篇文章里小編給大家整理了一篇關(guān)于python中waitKey實(shí)例用法講解,有興趣的朋友們可以參考學(xué)習(xí)下。
    2021-04-04
  • Python之時(shí)間和日期使用小結(jié)

    Python之時(shí)間和日期使用小結(jié)

    這篇文章主要介紹了Python之時(shí)間和日期使用小結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-02-02
  • 淺析Python語言自帶的數(shù)據(jù)結(jié)構(gòu)有哪些

    淺析Python語言自帶的數(shù)據(jù)結(jié)構(gòu)有哪些

    Python已經(jīng)廣泛的應(yīng)用于數(shù)據(jù)分析、數(shù)據(jù)挖掘、機(jī)器學(xué)習(xí)等眾多科學(xué)計(jì)算領(lǐng)域,這篇文章主要介紹了Python語言自帶的數(shù)據(jù)結(jié)構(gòu)有哪些?需要的朋友可以參考下
    2019-08-08
  • 使用Python和OpenCV實(shí)現(xiàn)實(shí)時(shí)文檔掃描與矯正系統(tǒng)

    使用Python和OpenCV實(shí)現(xiàn)實(shí)時(shí)文檔掃描與矯正系統(tǒng)

    在日常工作和學(xué)習(xí)中,我們經(jīng)常需要將紙質(zhì)文檔數(shù)字化,手動(dòng)拍攝文檔照片常常會(huì)出現(xiàn)角度傾斜、透?視變形等問題,影響后續(xù)使用,本文將介紹如何使用Python和OpenCV構(gòu)建一個(gè)實(shí)時(shí)文檔掃描與矯正系統(tǒng),能夠通過攝像頭自動(dòng)檢測文檔邊緣并進(jìn)行透?視變換矯正,需要的朋友可以參考下
    2025-05-05

最新評論

清水河县| 朝阳市| 苍山县| 岳池县| 犍为县| 昌宁县| 厦门市| 和静县| 湖南省| 正镶白旗| 高台县| 城口县| 岱山县| 南投市| 广东省| 原阳县| 柳林县| 石门县| 陈巴尔虎旗| 三穗县| 怀仁县| 左云县| 沂源县| 黄浦区| 水城县| 东兴市| 昌宁县| 沐川县| 余庆县| 泾阳县| 保亭| 阳曲县| 岫岩| 巩义市| 隆林| 阳城县| 晋宁县| 济阳县| 井陉县| 泰宁县| 墨脱县|