2016-12-16 57 views
5

我有一個很大的TXT(ipaddress.txt)有很多線的搜索字符串,每一行是一個IP地址,例如:德爾福:在TStringList中

44.XXX.XXX.XXX 
45.XXX.XXX.XXX 
46.XXX.XXX.XXX 
47.XXX.XXX.XXX 
48.XXX.XXX.XXX 

我在TStringList加載這個名單如:

FIpAddressList := TStringList.Create(); 
FIpAddressList.Sorted := true; 
FIpAddressList.LoadFromFile('ipaddress.txt'); 

,我想檢查一個IP地址在列表中,如:

function IsIPinList(const IPAddress : string): Boolean; 
begin 
    Result := (FIpAddressList.IndexOf(IPAddress) <> -1); 
end; 

它的作品...但與擁抱慢e TStringList

有什麼辦法讓這個過程更快?

UPDATE

  • 列表是靜態的,其中每月更新,以較少或更多5'000線。
  • 該函數在服務器上的每個請求上被調用(例如,每秒5次)。
  • 該列表僅在服務器服務啓動時加載。使這個快速
+0

有許多方法可以完成你想要的功能:通過數據庫,二叉樹,散列表等等。它取決於你的列表有多大,如果它發生變化,你的應用程序和環境的限制。 – RBA

+0

你可以使用 - 例如 - http://www.soft-gems.net/index.php/controls/virtual-treeview這是非常快的。 – RBA

+0

嘗試排序並嘗試二進制搜索算法後 – am2

回答

10

一種方法是使可使用二進制搜索來進行搜索列表安排進行排序,O(log n)的,而不是線性搜索,爲O(n)。

如果列表是靜態的,那麼最好的辦法是將列表排序在程序外部,以便您可以精確排序一次。

如果列表更具動態性,那麼您將不得不對其排序,並且保留所有修改的順序。在這種情況下,如果您進行的搜索次數足以克服排序和維護訂單的額外成本,那麼對列表進行排序只會帶來好處。

另一種方法是使用包含您的項目的字典。通常這將涉及散列每個字符串。雖然查找複雜度爲O(n),但哈希成本可能很高。

另一種加快速度的方法是將IP地址字符串轉換爲32位整數。事實上,這肯定會帶來巨大的性能收益,無論其他擔憂如何,您都應該這樣做。使用32位整數比IP地址的字符串表示更快速和更清晰。

這些只是一些可能的方法,還有更多。選擇哪一個取決於使用權衡。

雖然你可能只是尋找一些代碼來解決你的問題,但我認爲這個問題比基於代碼更具算法性。在選擇算法之前,您需要更好地理解需求,數據大小限制等。一旦你確定了一個算法,或者縮小了選擇的範圍以便進行比較,實現應該很簡單。


另一種可能性是您誤診了您的問題。即使在作爲字符串存儲的5000個IP地址的列表線性搜索要快於您報告:

  • 我的電腦可以搜索這樣的列表2000次第二使用線性搜索。
  • 一旦您對列表進行排序並切換到二分查找,則它可以每秒管理1,000,000次搜索。
  • 切換到存儲整數的有序數組,每秒鐘可以實現超過10,000,000次搜索。
  • 使用基於散列的整數字典可使性能再次提高兩倍。

因此,您的搜索性能可以輕鬆地提高2萬倍,但我仍然認爲您的性能問題不符合您的想法。我想知道,每次搜索時,您是否正在從磁盤讀取文件的真正問題。

+0

非常感謝你的幫助! – ar099968

+0

在您回答更新後,我已經調查過...每個函數調用都會加載列表,這會導致性能問題。謝謝大衛! – ar099968

+9

好。我認爲這裏有一個教訓。也就是說,理解和發現問題確實是最重要的任務。一旦你這樣做了,通常這個解決方案就顯得很平淡。 –