2011-11-28 66 views
4

我有一個問題,我現在的算法使用一種天真的線性搜索算法,通過匹配字符串從多個數據文件中檢索數據。在Perl中更快地搜索文件

它是這樣的(僞代碼):

while count < total number of files 
    open current file 
    extract line from this file 
    build an arrayofStrings from this line 

    foreach string in arrayofStrings 
      foreach file in arrayofDataReferenceFiles 
       search in these files 

    close file 
    increment count 

對於一個大的現實生活的工作,這個過程可能需要大約6個小時才能完成。

基本上我有一大組字符串,它使用程序來搜索相同的一組文件(例如,在1個實例中爲10個,在程序運行的下一個實例中爲3個)。由於參考數據文件可以改變,我不認爲建立這些文件的永久索引是明智的。

我幾乎是一個初學者,並沒有意識到任何更快的未排序數據技術。

我一直在思考,因爲搜索在一段時間後重復使用,是否有可能在數據引用文件中預建特定行的位置索引,而不使用任何外部perl庫(構建文件數組後) ?該腳本將被移植到可能只安裝了標準Perl的服務器上。

我認爲在處理工作之前花3-5分鐘建立某種搜索索引可能是值得的。

有索引/搜索適用於我的情況的具體概念嗎?

謝謝大家!

回答

1

你也許可以取代這個:有預處理步驟,以建立一個DBM文件

foreach file in arrayofDataReferenceFiles 
    search in these files 

(即磁盤上的哈希值)作爲每個單詞映射在你的參考文件列表的反向指標包含該詞的文件(或任何你需要的)。 Perl的核心includes DBM support

dbmopen HASH,DBNAME,MASK

此結合一個DBM(3),NDBM(3),SDBM(3),GDBM(3),或伯克利DB文件哈希。

你通常通過tie訪問此東西,但是這並不重要,每個Perl應該有一定的支持,至少一個散列的磁盤上的庫,而無需安裝的非核心包。

3

難以準確理解你想要達到的目標。

我假設數據集不適合RAM。

如果您試圖將許多文件中的每一行與一組模式進行匹配,則最好一次讀取每行,然後將其與內存中的所有模式進行匹配,然後再繼續前進。這將減少每個模式的循環IO。另一方面,如果匹配是花費時間,那麼最好使用可以同時匹配大量模式的庫。

+0

謝謝,這有助於減少我的處理時間,只需在處理內存時匹配所有內容即可。 – urbanspr1nter

1

正如MarkR所說,你想從每個文件中讀取每行不超過一次。您發佈的僞代碼看起來像是在多次讀取每個文件的每一行(對於搜索的每個單詞都是一次),這會顯着減慢速度,特別是在大型搜索時。反轉兩個最內層循環的順序應該(通過張貼的僞代碼來判斷)解決這個問題。

但是,您也說過,「由於參考數據文件可能會發生變化,所以我認爲建立這些文件的永久索引並不明智」這很可能是錯誤的。如果性能是一個問題(如果你需要6小時的運行時間,那麼我認爲這可能會成爲問題),平均而言,每個文件在對該特定文件的更改之間讀取不止一次,然後構建索引在磁盤上(甚至......使用數據庫!)將是一件非常聰明的事情。現在磁盤空間非常便宜;人們花在等待結果上的時間不是。

即使文件經常在不被讀取的情況下經歷多個更改,按需索引(當您想檢查文件時,首先查看索引是否存在,如果不存在,則在執行搜索之前構建一個索引)將是一個很好的方法 - 當一個文件被多次搜索時,您從索引中受益;如果沒有,首先建立索引,然後從索引中搜索將比線性搜索要慢得多,因爲這在很大程度上是無關緊要的。