2016-04-03 57 views
3

因此,我已經在Python 2中編寫了一個自動完成和自動更正程序。我已經使用上述方法編寫了自動更正程序,是Peter Norvig的博客,其中介紹瞭如何編寫拼寫檢查程序link爲自動更正程序快速保存和檢索python數據結構?

現在,我正在使用使用嵌套列表實現的trie數據結構。我使用了一個trie,因爲它可以給我所有以特定前綴開始的單詞。葉子將是一個元組,其中包含單詞和一個表示單詞頻率的值。例如,bad,bat,cat是保存爲 -

['b'['a'['d',('bad',4),'t',('bat',3)]],'c'['a'['t',('cat',4)]]] 

其中4,3,4是單詞已被使用的次數或頻率值。同樣,我已經制作了約130,000字的英文字典,並使用cPickle進行存儲。

現在,每次讀取整個樹的時間大約需要3-4秒。問題是每遇到一個字遇到頻率值必須遞增,然後需要再次保存更新的樹。正如你可以想象的那樣,每次讀取3-4秒都會有一個很大的問題,然後再次花費大量時間來保存每次更新的trie。每次程序運行時我都需要執行很多更新操作並保存它們。

是否有更快或更有效的方式來存儲重複更新的大型數據結構?在IDE和移動設備中自動更正程序的數據結構如何保存&如此快地獲取?我也接受不同的方法。

回答

2

想到幾件事情。

1)拆分數據。假設使用26個文件,每個文件存儲從某個字符開始的嘗試。您可以改進它,以便使用前綴。這樣,您需要編寫的數據量就會減少。

2)不要將所有內容都反映到磁盤上。如果您需要執行大量操作,請在RAM(內存)中執行它們,然後在最後寫下它們。如果您擔心數據丟失,您可以在X或某些操作後檢查點計算。

3)多線程。除非您只編寫拼寫檢查程序,否則可能還有其他需要做的事情。有一個單獨的線程可以加載寫入,以便在執行磁盤IO時不會阻塞所有內容。 Python中的多線程有點棘手,但可以完成。

4)自定義結構。在序列化中花費的部分時間是調用序列化函數。既然你有一個很多函數調用的字典。在完美的情況下,您應該有一個與磁盤表示完全匹配的內存表示。然後,您只需讀取一個大字符串並將其放入您的自定義類(並在需要時將該字符串寫入磁盤)。這有點更先進了,可能的好處並不是那麼大,特別是因爲python在玩比特幣方面效率不高,但如果你需要從速度中擠出最後一點速度,這是一條路。

+1

@gospelslide:你可能想看看'klepto'包(我是作者),它是爲了方便上面的優秀建議而構建的。 –

1

我建議你將序列化移動到一個單獨的線程並定期運行它。您不必每次重新讀取數據,因爲您已經擁有最新的內存版本。這樣,當數據被保存到磁盤時,您的程序將對用戶做出響應。磁盤上保存的版本可能會滯後,並且在程序崩潰的情況下最新的更新可能會丟失,但這對我們的用例來說應該不是什麼大問題,我想。

這取決於特定的用例和環境,但我認爲,大多數具有本地數據集的程序使用多線程來同步它們。