搜尋
首頁後端開發Python教學'警戒時間複雜度陷阱”

“Be wary of time complexity pitfalls

警惕時間複雜度陷阱

寫在這裡

bilibili視頻也顯示了這個:[Bilibili視頻][https://www.bilibili.com/video/BV16u4m1c7cU/?spm_id_from=333.999.0.0]我認為這是一個很好的視頻,但它的語言是中文。

時間複雜度

  • 時間複雜度是什麼意思?
  • 時間複雜度是演算法運行所需時間的度量,作為其輸入大小的函數。它是一種描述演算法效率的方式,用於比較不同的演算法並確定哪種演算法最有效。

  • 如何計算時間複雜度?

  • 為了計算時間複雜度,我們需要考慮演算法執行的運算元作為輸入大小的函數。測量操作次數最常見的方法是計算特定操作執行的次數。

  • 計算時間複雜度時有哪些常見陷阱?

    1. 不考慮輸入大小:如果我們只考慮演算法執行的操作數量,我們可能會低估時間複雜度。例如,如果我們計算循環運行的次數,但不考慮輸入的大小,那麼時間複雜度可能會太高。
    1. 不考慮演算法的效率:有些演算法即使輸入量很小也可能執行很多操作,這可能導致時間複雜度很高。例如,冒泡排序和選擇排序等排序演算法具有二次時間複雜度,即使它們可能只需要交換小數組中的兩個元素。
    1. 不考慮演算法的最壞情況:某些演算法具有最佳情況,其中執行的操作少於最壞情況。例如,像二分搜尋這樣的搜尋演算法有一個最好的情況,即它們在對數時間內找到目標元素,但它們有一個最壞的情況,即它們需要檢查數組中的所有元素。

讓我們來看一些時間複雜度的例子

這裡有個問題:
尋找清單中最多 10 個整數。

import random
ls = [random.randint(1, 100) for _ in range(n)]

這是測試函數:

import time
def benchmark(func, *args) -> float:
    start = time.perf_counter()
    func(*args)
    end = time.perf_counter()
    return end - start

解決方案1:使用堆

這是使用 heapq 模組的解決方案:

def find_max_n(ls, n):
    import heapq
    return heapq.nlargest(n, ls)

或者我們用python的方式來寫:

def find_largest_n(nums, n):
    if n  max_heap[0]:
            max_heap[0] = num
            _sift_down(max_heap, 0)

    return max_heap

def _sift_down(heap, index):
    left = 2 * index + 1
    right = 2 * index + 2
    largest = index

    if left  heap[largest]:
        largest = left

    if right  heap[largest]:
        largest = right

    if largest != index:
        heap[index], heap[largest] = heap[largest], heap[index]
        _sift_down(heap, largest)

解決方案2:使用排序

這是使用排序功能的解決方案:

def find_max_n(ls, n):
    return sorted(ls, reverse=True)[:n]

幾乎所有人都知道,堆的時間複雜度是 O(n log k),排序函數的時間複雜度是 O(n log n)。

看來第一個解決方案比第二個更好。但在 python 中卻並非如此。

看最終程式碼:

import time
def benchmark(func, *args) -> float:
    start = time.perf_counter()
    func(*args)
    end = time.perf_counter()
    return end - start

def find_max_n_heapq(ls, n):
    import heapq
    return heapq.nlargest(n, ls)

def find_max_n_python_heap(nums, n):
    if n  max_heap[0]:
            max_heap[0] = num
            _sift_down(max_heap, 0)

    return max_heap

def _sift_down(heap, index):
    left = 2 * index + 1
    right = 2 * index + 2
    largest = index

    if left  heap[largest]:
        largest = left

    if right  heap[largest]:
        largest = right

    if largest != index:
        heap[index], heap[largest] = heap[largest], heap[index]
        _sift_down(heap, largest)


def find_max_n_sorted(ls, n):
    return sorted(ls, reverse=True)[:n]

# test
import random
for n in range(10, 10000, 100):
    ls = [random.randint(1, 100) for _ in range(n)]
    print(f"n = {n}")
    print(f"Use    Heapq: {benchmark(find_max_n_heapq, ls, n)}")
    print(f"Python Heapq: {benchmark(find_max_n_python_heap, ls, n)}")
    print(f"Sorted      : {benchmark(find_max_n_sorted, ls, n)}")

我在Python3.11 VScode中運行它,結果如下:

n 不大

使用Heapq:0.002430099993944168
Python 堆:0.06343129999004304
排序:9.280000813305378e-05
n = 910
使用堆:9.220000356435776e-05
Python 堆:0.07715500006452203
排序:9.360001422464848e-05
n = 920
使用堆:9.440002031624317e-05
Python 堆:0.06573969998862594
排序:0.00012450001668184996
n = 930
使用Heapq:9.689992293715477e-05
Python 堆:0.06760239996947348
排序:9.66999214142561e-05
n = 940
使用堆:9.600003249943256e-05
Python 堆:0.07372559991199523
排序:9.680003859102726e-05
n = 950
使用堆:9.770004544407129e-05
Python 堆:0.07306570000946522
排序:0.00011979998089373112
n = 960
使用堆:9.980006143450737e-05
Python 堆:0.0771204000338912
排序:0.00022829999215900898
n = 970
使用Heapq:0.0001601999392732978
Python 堆:0.07493270002305508
排序:0.00010840001050382853
n = 980
使用堆:9.949994273483753e-05
Python 堆:0.07698320003692061
排序:0.00010300008580088615
n = 990
使用堆:9.979994501918554e-05
Python 堆:0.0848745999392122
排序:0.00012620002962648869

如果n很大?

n = 10000
使用Heapq:0.003642000025138259
Python 堆:9.698883199947886
排序:0.00107999995816499
n = 11000
使用Heapq:0.0014836000045761466
Python 堆:10.537632800056599
排序:0.0012236000038683414
n = 12000
使用Heapq:0.001384599949233234
Python 堆:12.328411899972707
排序:0.0013226999435573816
n = 13000
使用Heapq:0.0020017001079395413
Python 堆:15.637207800056785
排序:0.0015075999544933438
n = 14000
使用Heapq:0.0017026999266818166
Python 堆:17.298848500009626
排序:0.0016967999981716275
n = 15000
使用Heapq:0.0017773000290617347
Python 堆:20.780625900020823
排序:0.0017105999868363142

我發現了什麼以及如何改進它

當n很大時,Sorted會花費一點時間(有時甚至比使用heapq更好),但Python Heapq會花費很多時間。

  • 為什麼Sorted花一點時間,而Python Heapq花很多時間?
  • 因為sorted()是Python中內建的函數,所以你可以找到關於它的Python官方文件。

內建函數比 heapq 更快,因為它是用 C 寫的,C 是一種編譯語言。

  • 如何改進?
  • 您可以使用內建函數sorted()來取代heapq.sort()來提高程式碼的效能。 Sorted() 函數是 Python 中的內建函數,它是用 C 實現的,因此比 heapq.sort() 快得多

腦震盪

當我們處理大數據時,我們應該使用內建函數而不是 heapq.sort() 來提高程式碼的效能。在處理大數據時,我們必須警惕時間複雜度陷阱。有時時間複雜度的陷阱是不可避免的,但我們應該盡量避免它們。

關於我

大家好,我是夢沁園。我是一名學生。我喜歡學習新事物。
你可以看我的github:[MengQinYuan的Github][https://github.com/mengqinyuan]

以上是'警戒時間複雜度陷阱”的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
了解差異:用於循環和python中的循環了解差異:用於循環和python中的循環May 16, 2025 am 12:17 AM

theDifferenceBetweewneaforoopandawhileLoopInpythonisthataThataThataThataThataThataThataNumberoFiterationSiskNownInAdvance,而leleawhileLoopisusedWhenaconDitionNeedneedneedneedNeedStobeCheckedStobeCheckedStobeCheckedStobeCheckedStobeceDrepeTysepectients.peatsiveSectlyStheStobeCeptellyWithnumberofiterations.1)forloopsareAceareIdealForitoringercortersence

Python循環控制:對於vs -a -a比較Python循環控制:對於vs -a -a比較May 16, 2025 am 12:16 AM

在Python中,for循環適用於已知迭代次數的情況,而while循環適合未知迭代次數且需要更多控制的情況。 1)for循環適用於遍歷序列,如列表、字符串等,代碼簡潔且Pythonic。 2)while循環在需要根據條件控制循環或等待用戶輸入時更合適,但需注意避免無限循環。 3)性能上,for循環略快,但差異通常不大。選擇合適的循環類型可以提高代碼的效率和可讀性。

如何在Python中結合兩個列表:5種簡單的方法如何在Python中結合兩個列表:5種簡單的方法May 16, 2025 am 12:16 AM

在Python中,可以通過五種方法合併列表:1)使用 運算符,簡單直觀,適用於小列表;2)使用extend()方法,直接修改原列表,適用於需要頻繁更新的列表;3)使用列表解析式,簡潔且可對元素進行操作;4)使用itertools.chain()函數,內存高效,適合大數據集;5)使用*運算符和zip()函數,適用於需要配對元素的場景。每種方法都有其特定用途和優缺點,選擇時應考慮項目需求和性能。

循環時循環:python語法,用例和示例循環時循環:python語法,用例和示例May 16, 2025 am 12:14 AM

foroopsare whenthenemberofiterationsisknown,而whileLoopsareUseduntilacTitionismet.1)ForloopSareIdealForeSequencesLikeLists,UsingSyntaxLike'forfruitinFruitinFruitinFruitIts:print(fruit)'。 2)'

python串聯列表列表python串聯列表列表May 16, 2025 am 12:08 AM

toConcateNateAlistofListsInpython,useextend,listComprehensions,itertools.Chain,orrecursiveFunctions.1)ExtendMethodStraightForwardButverBose.2)listComprechencomprechensionsareconconconciseandemandeconeandefforlargerdatasets.3)

Python中的合併列表:選擇正確的方法Python中的合併列表:選擇正確的方法May 14, 2025 am 12:11 AM

Tomergelistsinpython,YouCanusethe操作員,estextMethod,ListComprehension,Oritertools

如何在Python 3中加入兩個列表?如何在Python 3中加入兩個列表?May 14, 2025 am 12:09 AM

在Python3中,可以通過多種方法連接兩個列表:1)使用 運算符,適用於小列表,但對大列表效率低;2)使用extend方法,適用於大列表,內存效率高,但會修改原列表;3)使用*運算符,適用於合併多個列表,不修改原列表;4)使用itertools.chain,適用於大數據集,內存效率高。

Python串聯列表字符串Python串聯列表字符串May 14, 2025 am 12:08 AM

使用join()方法是Python中從列表連接字符串最有效的方法。 1)使用join()方法高效且易讀。 2)循環使用 運算符對大列表效率低。 3)列表推導式與join()結合適用於需要轉換的場景。 4)reduce()方法適用於其他類型歸約,但對字符串連接效率低。完整句子結束。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)