我有一堆包含300k行的txt
文件。每条线都有一个URL
。例如http://www.ieee.org/conferences_events/conferences/conferencedetails/index.html?Conf_ID=30718
在一些string[]
数组中,我有一个网站列表
amazon.com
google.com
ieee.org
...
我需要检查
URL
是否包含某个网站,并更新对应于某个网站的计数器?目前我正在使用
contains
方法,但它非常慢。数组中有大约900条记录,所以最坏的情况是900*300K(对于1个文件)。我相信,indexOf
也会很慢。有人能帮我快点吗?提前谢谢你
最佳答案
好的解决方案将利用散列。我的方法是
散列所有已知主机(您提到的string[]
集合)
将散列存储在List<int>
(hashes.Add("www.ieee.com".GetHashCode()
中)
对列表进行排序(hashes.Sort()
)
查找URL时:
从url解析出主机名(从ieee.com
获取http://www.ieee.com/...
)。您可以使用new Uri("http://www.ieee.com/...").Host
来获取www.ieee.com
。
对它进行预处理,使其始终期望相同的情况。使用小写(如果您有http://www.IEee.COM/
Takewww.ieee.com
)
哈希分析的主机名,并在hashes
列表中查找。使用BinarySearch
方法查找散列。
如果哈希存在,那么在列表中有这个主机
更快、更节省内存的方法是使用Bloom filters。我建议你在维基百科上读到它们,甚至还有一个bloom filteron CodePlex的c实现。当然,您需要考虑到bloom filter允许假阳性结果(它可以告诉您一个值在集合中,即使它不在集合中),所以它只用于优化。它不会告诉你某个东西不在集合中,如果它真的不在集合中。
使用Dictionary<TKey, TValue>
也是一个选项,但是如果您只需要计算出现次数,那么您自己维护散列集合的效率会更高。