<dd id="sga4y"><optgroup id="sga4y"></optgroup></dd>
<nav id="sga4y"><code id="sga4y"></code></nav>
  • <optgroup id="sga4y"></optgroup>

    18.6. 優化字符串操作

    Soundex 算法的最后一步是對短結果補零和截短長結果。最佳的做法是什么?

    這是目前在 soundex/stage2/soundex2c.py 中的做法:

        digits3 = re.sub('9', '', digits2)
        while len(digits3) < 4:
            digits3 += "0"
        return digits3[:4]
    

    這里是 soundex2c.py 的表現:

    C:\samples\soundex\stage2>python soundex2c.py
    Woo             W000 12.6070768771
    Pilgrim         P426 14.4033353401
    Flingjingwaller F452 19.7774882003
    

    思考的第一件事是以循環取代正則表達式。這里的代碼來自 soundex/stage4/soundex4a.py

        digits3 = ''
        for d in digits2:
            if d != '9':
                digits3 += d
    

    soundex4a.py 快了嗎?是的:

    C:\samples\soundex\stage4>python soundex4a.py
    Woo             W000 6.62865531792
    Pilgrim         P426 9.02247576158
    Flingjingwaller F452 13.6328416042
    

    但是,等一下。一個從字符串去除字符的循環?我們可以用一個簡單的字符串方法做到。這便是 soundex/stage4/soundex4b.py

        digits3 = digits2.replace('9', '')
    

    soundex4b.py 快了嗎?這是個有趣的問題,它取決輸入值:

    C:\samples\soundex\stage4>python soundex4b.py
    Woo             W000 6.75477414029
    Pilgrim         P426 7.56652144337
    Flingjingwaller F452 10.8727729362
    

    soundex4b.py 中的字符串方法對于大多數名字比循環快,但是對于短小的情況 (很短的名字) 卻比 soundex4a.py 略微慢些。性能優化并不總是一致的,對于一個情況快些,卻可能對另外一些情況慢些。就此而言,大多數情況將會從改變中獲益,所以就改吧,但是別忘了原則。

    最后仍很重要的是,讓我們檢測算法的最后兩步:以零補齊短結果和截短超過四字符的長結果。你在 soundex4b.py 中看到的代碼就是做這個工作的,但是太沒效率了。看一下 soundex/stage4/soundex4c.py 找出原因:

        digits3 += '000'
        return digits3[:4]
    

    我們為什么需要一個 while 循環來補齊結果?我們早就知道我們需要把結果截成四字符,并且我們知道我們已經有了至少一個字符 (直接從 source 中拿過來的起始字符)。這意味著我們可以僅僅在輸出的結尾添加三個零,然后截斷它。不要害怕重新理解問題,從不太一樣的角度看問題可以獲得簡單的解決方案。

    我們丟棄 while 循環后從 soundex4c.py 中獲得怎樣的速度?太明顯了:

    C:\samples\soundex\stage4>python soundex4c.py
    Woo             W000 4.89129791636
    Pilgrim         P426 7.30642134685
    Flingjingwaller F452 10.689832367
    

    最后,還有一件事可以令這三行運行得更快:你可以把它們合并為一行。看一眼 soundex/stage4/soundex4d.py

        return (digits2.replace('9', '') + '000')[:4]
    

    soundex4d.py 中把所有代碼放在一行可以比 soundex4c.py 稍微快那么一點:

    C:\samples\soundex\stage4>python soundex4d.py
    Woo             W000 4.93624105857
    Pilgrim         P426 7.19747593619
    Flingjingwaller F452 10.5490700634
    

    它非常難懂,而且優化也不明顯。這值得嗎?我希望你有很好的見解。性能并不是一切。你在優化方面的努力應該與程序的可讀性和可維護性相平衡。

    97av