2016-12-16 47 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

好。我认为这里有一个教训。也就是说,理解和发现问题确实是最重要的任务。一旦你这样做了,通常这个解决方案就显得很平淡。 –