Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于快速筛选的.net集合(已排序集合)_C#_Sorting_Collections_C5 - Fatal编程技术网

C# 用于快速筛选的.net集合(已排序集合)

C# 用于快速筛选的.net集合(已排序集合),c#,sorting,collections,c5,C#,Sorting,Collections,C5,在分析一个非常慢的方法时,我发现搜索和筛选集合的过程存在滞后 该方法(按顺序)执行以下操作。根据profiler,80%的时间花在步骤1-3上 从文件中读取已排序的集合并使用Protobuf net(v2)反序列化 从已排序的集合中,根据开始和结束整数(name.RangeFromTo())进行筛选 从同一个已排序的集合中,获取集合的下一个元素(name.Right()) 执行一些任务 .RangeFromTo()为给定范围筛选,例如: [3,7,9,12].RangeFromTo(2,9) -

在分析一个非常慢的方法时,我发现搜索和筛选集合的过程存在滞后

该方法(按顺序)执行以下操作。根据profiler,80%的时间花在步骤1-3上

  • 从文件中读取已排序的集合并使用Protobuf net(v2)反序列化
  • 从已排序的集合中,根据开始和结束整数(name
    .RangeFromTo()
    )进行筛选
  • 从同一个已排序的集合中,获取集合的下一个元素(name.
    Right()
  • 执行一些任务
  • .RangeFromTo()
    为给定范围筛选,例如:

    [3,7,9,12].RangeFromTo(2,9) -> [3,7,9]
    [3,7,9,12].RangeFromTo(2,8) -> [3,7]
    [3,7,9,12].RangeFromTo(7,13) -> [7,9,12]
    [3,7,9,12].RangeFromTo(13,14) -> [ ]
    
    [3,7,9,12].Right(0) -> 3
    [3,7,9,12].Right(3) -> 7
    [3,7,9,12].Right(4) -> 7
    [3,7,9,12].Right(12) -> null
    
    indexer: [0,0,0,0,1,1,1,1,2,2]
    list: [3,7,9]
    
    .Right()
    在集合中查找一个元素,并为您提供列表中的下一个元素。如果该元素不存在,它将为您提供最接近右侧的元素。例如:

    [3,7,9,12].RangeFromTo(2,9) -> [3,7,9]
    [3,7,9,12].RangeFromTo(2,8) -> [3,7]
    [3,7,9,12].RangeFromTo(7,13) -> [7,9,12]
    [3,7,9,12].RangeFromTo(13,14) -> [ ]
    
    [3,7,9,12].Right(0) -> 3
    [3,7,9,12].Right(3) -> 7
    [3,7,9,12].Right(4) -> 7
    [3,7,9,12].Right(12) -> null
    
    indexer: [0,0,0,0,1,1,1,1,2,2]
    list: [3,7,9]
    
    目前该集合正在使用C5()中的
    SortedArray
    。有更适合我使用的收藏吗

    注: 第一步。大约占总时间的30%。如果我改用列表,protobuf反序列化的时间实际上减少了40%!我猜当插入SorterDarray时,集合不知道数据已经被排序,并且正在做大量的工作。理想的集合(如果存在)也应该能够绕过它

    编辑: 要澄清的是,该列表大约有1000-5000个,有90k个不同的集合!该方法需要加载内存中的所有集合以执行某些业务任务

    编辑2: 我在这里添加了一些示例基准:

    它将C5中的
    SortedArray
    与.Net中的
    SortedSet
    进行比较。到目前为止,结果如下:

    C5 sorted array deserialize took 904
    Sorted set deserialize took 1040
    C5 sorted array .Right() took 5
    Sorted set .Right() took 798    <--- Not sure what happened here...
    C5 sorted array .RangeFromTo() took 217
    Sorted set .RangeFromTo() took 140
    
    因此,
    .Right(3)
    将是
    list[indexer[3]+]

    代码可以找到

    很难相信这种类型的列表在互联网上还没有实现。如果可能的话,我想使用一个库,这样我就不必管理自己的列表


    互联网上有这样的实现吗?

    如果你的数组足够小(可能在10-20个元素以下),那么简单的线性搜索很有可能足够好(这在某种程度上可以通过
    列表
    在你的测量中速度更快来体现),你可以用
    Where
    /
    TakeWhile
    :

      (new[]{3,7,9,12}).Where(i => i>= 2).TakeWhile(i => i <= 9)
    

    (new[]{3,7,9,12}).Where(i=>i>=2).TakeWhile(i=>我可以使用吗?我怀疑这会有同样的“它已经排序”问题,但是如果您先反序列化到列表,然后创建
    SortedSet
    (或
    SortedArray
    )在一个步骤中,这可能会更有效。谢谢,我将首先尝试一下,并将结果发布在这里。@JonSkeet,我已经更新了问题,还添加了SortedSet的测试。SortedSet的性能不如C5实现。不幸的是:(.谢谢,我想使用3,7,9,12不是一个很好的例子。该列表大约有1000-5000个集合,有90k个不同的集合!该方法需要加载内存中的所有集合以执行一些业务任务。@ChiChan-(请使用数组和范围的此项计数更新您的问题)考虑手工编码二进制搜索的第一个元素(<代码>右< /代码>),看看你是否得到更好的结果…还取决于范围是多大,如果你花所有的时间复制大范围作为数组/列表,它可能没有帮助。我更新了这个问题,并添加了一些分支标记代码。(Log(N))因此,要改进这一点,我需要比这更快。我现在确实制作了一个自定义列表,但不知道互联网上是否存在这样的列表。