簡體   English   中英

為什么在字典中查找要比Python中的兩個if-tests快得多?

[英]Why is lookup in dictionary much faster than two if-tests in Python?

我需要閱讀千兆字節的文本,所以我正在嘗試優化我的代碼。 這樣做時,我發現,對於我的問題,使用字典比if-tests更快。

check = {'R':'-', 'F':'+'}
seqs = ['R', 'F']*100

def check1():
    for entry in seqs:
        if entry == 'R':
            strand = '-'
        if entry == 'F':
            strand = '+'

def check2():
    for entry in seqs:
        strand = check[entry]

使用ipythong的%timeit我發現在字典中查找的速度比使用兩個if-tests快兩倍:

In [63]: %timeit check1()
10000 loops, best of 3: 38.8 us per loop

In [64]: %timeit check2()
100000 loops, best of 3: 16.2 us per loop

由於if-tests是如此基本,我沒想到性能差異。 這是眾所周知的嗎? 任何人都可以解釋為什么會這樣嗎?

UPDATE

我檢查了上面的兩個函數以及下面的check3()如何影響我的實際代碼的運行時間,並且對總時間沒有影響。 因此,在現實世界的例子中,要么字典中的提升不是那么高,其中'R'和'F'值需要不斷地從文件中重新讀取,或者這段代碼不是我的瓶頸的一部分。

無論如何,謝謝你的答案!

你還沒有真正證明, if測試,在字典中查找比兩個更快。 你所展示的是,查找特定字典比這兩個測試更快。

通常,字典查找需要幾個步驟:從密鑰生成哈希以找到潛在匹配,然后通過比較密鑰來測試潛在匹配。 如果存在哈希表沖突,有時可能需要進行多次比較。 如果你有用戶定義的鍵類,那么這兩個步驟都可能很慢,它們通常對字符串很快,但在一個特殊情況下它們真的非常快,你已經遇到了這種情況。

您的字典使用的短字符串與編譯時已知的標識符格式相匹配。 Python將有助於“實踐”你的字符串'R'和'F'。 由於您在測試中使用的字符串在編譯時也是已知的,因此它們將是完全相同的實例。 對字典查找的所有這些意味着,查找的專用版本用於僅具有字符串鍵的字典,哈希始終是預先計算的,並且通過比較地址來進行密鑰比較(至少在成功時和您的它永遠不會失敗的兩把鑰匙)。

你的真實代碼,我假設是從輸入讀取字符串,所以它不會有'R'的實習副本。 這意味着它需要計算每行輸入的哈希值。 地址不匹配,因此必須為每個測試調用字符串比較函數。 你仍然只對字符串鍵進行一些優化,至少它不必對可能不是字符串的對象進行通用比較。

if語句對於對象類型一無所知,因此每次都會進行通用比較。

與許多VM代碼一樣,它主要歸結為涉及的VM操作碼數量。

您可以使用dis檢查已組合的函數:

import dis
dis.dis(func)

在2.6.4中,check1需要大約15-20個操作碼(取決於代碼路徑),用於每個比較和分支。 check2只需7(在添加缺失的chedict字典后,全局聲明)。

字典在Python中進行了大量優化; 查找是O(1) - 它只是一個哈希表查找,因此只是一個“操作” - 使用if測試序列(即O(n) )獲得的操作數量的一半。

這會揭示一些事情:

def check3():
    for entry in seqs:
        if entry == 'R':
            strand = '-'
        else:
            strand = '+'

它實際上比我的電腦上的check2()更快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM