C# C语言中的快速读取集合
我正在为以下场景寻找一个集合类: 快速集合查找,一次一项。 该系列包含约30万个项目。 收集人口的速度可能并不重要,但理想情况下也很快。 加载集合后,无需更新/删除/插入 将填充到集合中的Ip2Location类型的项的示例:C# C语言中的快速读取集合,c#,C#,我正在为以下场景寻找一个集合类: 快速集合查找,一次一项。 该系列包含约30万个项目。 收集人口的速度可能并不重要,但理想情况下也很快。 加载集合后,无需更新/删除/插入 将填充到集合中的Ip2Location类型的项的示例: public class Ip2Location { public long IpFrom {get; set;} public long IpTo {get; set;} public string Country {get; set;} } I
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
它适用于少量行,不适用于300k项,例如索引为-totalrow+1。搜索项加载到300k items集合中
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返回的索引仍然是nagative,它位于匹配项和后续项之间。e、 g.如果我的搜索IpFrom为3,则索引介于2和4之间。为什么它不返回2?我还没有测试IpTo场景
任何想法都将不胜感激 您可以将其存储在一个数组中
如果在填充后对数组进行排序,则查找当前IP的位置将是一种非常快速的方法。您可以将其存储在数组中
如果在填充后对数组进行排序,则查找当前IP所在位置的方法将非常快速。从数据结构角度看,您可以尝试使用字典或排序列表,尽管对于300000项,您可能会遇到问题。不过,我很想知道结果。带有BinarySearch的普通数组也可能是一个不错的选择
<>你也可以考虑利用机器上的所有内核进行快速查找。您可以在大多数集合上使用,这将为在多个核心上查询集合做好准备。从数据结构来看,您可以尝试使用字典或排序列表,尽管对于300000项,您可能会遇到问题。不过,我很想知道结果。带有BinarySearch的普通数组也可能是一个不错的选择
<>你也可以考虑利用机器上的所有内核进行快速查找。您可以在大多数集合上使用,这将为在多个核心上查询集合做好准备。谢谢!HashSet和SortedSet呢?你的意思是按IpFrom排序?因为IpFrom是唯一的。不,你需要一个数组和一个二进制搜索来搜索你正在做的事情。哈希集或排序列表必须进行查找,即使您可以对它们进行迭代,它们也不可能像二进制搜索那样有效。@用乒乓球将按IpFrom排序的普通数组与IpFrom上的二进制搜索一起使用谢谢!我将测试它,并发布结果。我在使用BinarySearch获取查找项时遇到问题。我把我的发现贴在更新部分。你能看一下吗?谢谢!HashSet和SortedSet呢?你的意思是按IpFrom排序?因为IpFrom是唯一的。不,你需要一个数组和一个二进制搜索来搜索你正在做的事情。哈希集或排序列表必须进行查找,即使您可以对它们进行迭代,它们也不可能像二进制搜索那样有效。@用乒乓球将按IpFrom排序的普通数组与IpFrom上的二进制搜索一起使用谢谢!我将测试它,并发布结果。我在使用BinarySearch获取查找项时遇到问题。我把我的发现贴在更新部分。你能看一下吗?你的搜索方法不起作用,因为你的比较器…坏了。如果x在y之前,则需要返回-1;如果x和y相同,则需要返回0;如果y在x之后,则需要返回1。在您的例子中,您几乎肯定希望实现为x.IpFrom.CompareToy.IpFrom,然后如果结果为零,则返回IpTo`比较,并进行空检查。这将为您提供范围内的第一项。然后继续,直到你找到一个目标范围在当前目标之前的目标,然后你就完成了。谢谢你的评论。我发布了更新2。请看一看,任何想法都将非常感谢!您的比较器现在显然工作正常。你可以用更少的代码来完成,但是你所拥有的并没有什么问题。BinarySearch设计为返回负值;只需查看MSDN上的方法文档和示例,了解其正确用法。谢谢!更新1中的比较器适用于具有少量行的测试用例,但不适用于300K项。知道吗?第一个比较器完全坏了。如果成功,那纯粹是运气,因为集合太小。你的搜索方法不起作用,因为你的比较器…坏了。如果x在y之前,则需要返回-1;如果x和y相同,则需要返回0;如果y在x之后,则需要返回1。在您的例子中,您几乎肯定希望实现为x.IpFrom.CompareToy.IpFrom,然后如果结果为零,则返回IpTo`比较,并进行空检查。这将为您提供范围内的第一项。然后继续,直到你找到一个目标范围在当前目标之前的目标,然后你就完成了。谢谢你的评论。我发布了更新2。请看一看,任何想法都将非常感谢!您的比较器现在已清除
我在工作。你可以用更少的代码来完成,但是你所拥有的并没有什么问题。BinarySearch设计为返回负值;只需查看MSDN上的方法文档和示例,了解其正确用法。谢谢!更新1中的比较器适用于具有少量行的测试用例,但不适用于300K项。知道吗?第一个比较器完全坏了。如果成功的话,那纯粹是运气,因为布景太小了。
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;
}