Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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# 跳过并接收Linq对象的性能_C#_Performance_Linq_Paging - Fatal编程技术网

C# 跳过并接收Linq对象的性能

C# 跳过并接收Linq对象的性能,c#,performance,linq,paging,C#,Performance,Linq,Paging,搜索“跳过”和“接受”功能的替代功能 链接的1表示“每次调用Skip()时,它都必须从头开始迭代您的集合,以跳过所需的元素数,从而在循环中产生循环(n2行为)” 结论:对于大量收集,不要使用Skip and Take。找到另一种方法来迭代并划分集合 为了在一个庞大的集合中访问最后一页数据,您能给我们建议一种除了“跳过”和“采取”方法之外的方法吗 取决于您的实现,但是使用索引数组来代替是有意义的。查看forSkip,您可以看到它枚举了所有项,甚至是要跳过的前n项。 但这很奇怪,因为有几种LINQ方

搜索“跳过”和“接受”功能的替代功能

链接的1表示“每次调用Skip()时,它都必须从头开始迭代您的集合,以跳过所需的元素数,从而在循环中产生循环(n2行为)”

结论:对于大量收集,不要使用Skip and Take。找到另一种方法来迭代并划分集合


为了在一个庞大的集合中访问最后一页数据,您能给我们建议一种除了“跳过”和“采取”方法之外的方法吗

取决于您的实现,但是使用索引数组来代替是有意义的。

查看for
Skip
,您可以看到它枚举了所有项,甚至是要跳过的前n项。
但这很奇怪,因为有几种LINQ方法对集合进行了优化,比如
Count
Last

Skip
显然没有

如果您有一个数组或
IList
,则可以使用索引器真正跳过它们:

for (int i = skipStartIndex; i < list.Count; i++) {
    yield return list[i];
}
for(int i=skipStartIndex;i
在内部,它确实是正确的:

private static IEnumerable<TSource> SkipIterator<TSource>(IEnumerable<TSource> source, int count)
{
  using (IEnumerator<TSource> enumerator = source.GetEnumerator())
  {
    while (count > 0 && enumerator.MoveNext())
      --count;
    if (count <= 0)
    {
      while (enumerator.MoveNext())
        yield return enumerator.Current;
    }
  }
}
private静态IEnumerable SkipIterator(IEnumerable源代码,int计数)
{
使用(IEnumerator enumerator=source.GetEnumerator())
{
while(计数>0&&enumerator.MoveNext())
--计数;

如果(计数迭代部分可能只适用于
IEnumerable
,如果
IList
没有使用索引,我会感到惊讶。@AlexanderDerck不幸的是没有-最近在corefx repo中实现了此优化。Jon Skeet谈到了优化Edulink系列和再次在第40部分:。我的观点是,他不一定认为这是一个好主意。也许。在第23节中,他对这个主题发表了各种各样的胡言乱语,但在第40节中,他似乎认为这不是一个好主意。@JasonBoyd,正如usr所说,corefx实际上已经进行了优化。对可观察到的变化进行了评估,但认为可以接受able.See取决于版本。当前已针对列表、
OrderBy
的结果和其他几种情况进行了优化,希望很快会有更多改进。请注意,
Skip()的当前行为
在一个
IList上
与您这里的功能非常接近。使用skip获取最后一页数据的效率很低。从20万条记录中提取最后100条记录需要花费近13秒。查看有价值的评论,我是否可以得出结论,我们不应该使用skip和Take获取大量数据。不,我们没有使用数组和列表.我们使用了延迟查询(IEnumerable)从数据库中获取数据。
public static class IReadOnlyListExtensions
{
    public static IEnumerable<T> Skip<T>(this IReadOnlyList<T> collection, int count)
    {
        if (collection == null)
            return null;

        return ICollectionExtensions.YieldSkip(collection, count);
    }

    private static IEnumerable<T> YieldSkip<T>(IReadOnlyList<T> collection, int count)
    {
        for (int index = count; index < collection.Count; index++)
        {
            yield return collection[index];
        }
    }
}
if (collection is IReadOnlyList<T>)
{
    // do optimized skip
}