C# C语言中的快速读取集合

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

我正在为以下场景寻找一个集合类:

快速集合查找,一次一项。 该系列包含约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
它适用于少量行,不适用于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;
}