我正在为以下场景寻找一个集合类:
- 快速查找集合,一次查找一项。
- 该集合包含大约 30 万件元素。
- 收集人口的速度可能并不重要,但最好也快。
- 集合加载后无需更新/删除/插入
将填充到集合中的 Ip2Location 类型的项目示例:
public class Ip2Location
{
public long IpFrom {get; set;}
public long IpTo {get; set;}
public string Country {get; set;}
}
IpFrom IpTo Country
16909056 16909311 AU
16909312 16941055 US
针对集合的项目查找是通过指定的 IP 完成的,如下所示:
IpFrom < currentIp < IpTo
任何想法,包括引用链接,将不胜感激!
比较:HashSet、SortedSet
有没有更好的集合类?
引用:下面链接中的对照表: http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx
更新:
使用 Array.BinarySearch 的问题:
var index = Array.BinarySearch(ipCountries, new IpCountry { IpFrom = 16909056}, new Ip2LocationComparer());
它适用于少量行,不适用于 300k 项(例如索引为 -(totalrow+1) )。搜索项目加载到 300 K 项目集合中。
public class Ip2LocationComparer: IComparer<IpCountry>
{
public int Compare(IpCountry x, IpCountry y)
{
if (x != null && y != null)
return (x.IpFrom <= y.IpFrom && y.IpFrom <= x.IpTo)? 0 : -1;
return -1;
}
}
更新 2
我改成了下面
public class Ip2LocationComparer: IComparer<IpCountry>
{
public int Compare(IpCountry x, IpCountry y)
{
if (x != null && y != null)
{
if (x.IpFrom > y.IpFrom)
return 1;
if (x.IpFrom < y.IpFrom)
return -1;
if (x.IpFrom == y.IpFrom)
{
if (y.IpFrom > x.IpTo)
return 1;
if (y.IpFrom < x.IpTo)
return -1;
}
}
return 0;
}
但是 BinarySearch 返回的索引仍然是负数,正好在匹配项和跟随项之间。例如如果我的搜索 IpFrom 是 3,索引在 2 到 4 之间。为什么它不返回 2?我还没有测试 IpTo 场景。
任何想法将不胜感激!
请您参考如下方法:
您可以将其存储在一个数组中。
如果您在填充后对数组进行排序,那么 BinarySearch将是查找 currentIp 所在位置的一种非常快速的方法。
