Skip 的性能(以及类似功能,如 Take)

2024-04-08

我刚刚看了一下源代码Skip/Take.NET Framework 的扩展方法(在IEnumerable<T>类型)并发现内部实现正在与GetEnumerator method:

// .NET framework
    public static IEnumerable<TSource> Skip<TSource>(this IEnumerable<TSource> source, int count)  
    {
        if (source == null) throw Error.ArgumentNull("source"); 
        return SkipIterator<TSource>(source, count); 
    }

    static IEnumerable<TSource> SkipIterator<TSource>(IEnumerable<TSource> source, int count) 
    {
        using (IEnumerator<TSource> e = source.GetEnumerator()) 
        {
            while (count > 0 && e.MoveNext()) count--;
            if (count <= 0) 
            { 
                while (e.MoveNext()) yield return e.Current;
            } 
        } 
    }

假设我有一个IEnumerable<T>有 1000 个元素(底层类型是List<T>)。如果我执行 list.Skip(990).Take(10) 会发生什么?它会在获取最后十个元素之前迭代前 990 个元素吗? (我是这样理解的)。如果是的话,那么我不明白为什么微软没有实施Skip像这样的方法:

    // Not tested... just to show the idea
    public static IEnumerable<T> Skip<T>(this IEnumerable<T> source, int count)
    {
        if (source is IList<T>)
        {
            IList<T> list = (IList<T>)source;
            for (int i = count; i < list.Count; i++)
            {
                yield return list[i];
            }
        }
        else if (source is IList)
        {
            IList list = (IList)source;
            for (int i = count; i < list.Count; i++)
            {
                yield return (T)list[i];
            }
        }
        else
        {
            // .NET framework
            using (IEnumerator<T> e = source.GetEnumerator())
            {
                while (count > 0 && e.MoveNext()) count--;
                if (count <= 0)
                {
                    while (e.MoveNext()) yield return e.Current;
                }
            }
        }
    }

事实上,他们这样做是为了Count方法例如...

    // .NET Framework...
    public static int Count<TSource>(this IEnumerable<TSource> source) 
    {
        if (source == null) throw Error.ArgumentNull("source");

        ICollection<TSource> collectionoft = source as ICollection<TSource>; 
        if (collectionoft != null) return collectionoft.Count;

        ICollection collection = source as ICollection; 
        if (collection != null) return collection.Count; 

        int count = 0;
        using (IEnumerator<TSource> e = source.GetEnumerator())
        { 
            checked 
            {
                while (e.MoveNext()) count++;
            }
        } 
        return count;
    } 

那么原因是什么呢?


在 Jon Skeet 的优秀教程中重新实现Linq https://codeblog.jonskeet.uk/2011/01/02/reimplementing-linq-to-objects-part-23-take-skip-takewhile-skipwhile/,他(简短地)讨论了这个问题:

尽管这些操作中的大多数都无法进行合理的优化,但它 当源实现 IList 时,优化 Skip 是有意义的。 我们可以跳过跳过,可以这么说,直接进入 适当的索引。这不会发现来源所在的情况 在迭代之间进行修改,这可能是它不是的原因之一 据我所知,已在框架中实现。

这似乎是推迟优化的合理理由,但我同意,对于特定情况,如果您可以保证您的源代码不能/不会被修改,那么进行优化可能是值得的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Skip 的性能(以及类似功能,如 Take) 的相关文章

  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 为什么 GCC 不允许我创建“内联静态 std::stringstream”?

    我将直接前往 MCVE include
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • mvc显示模板中当前项目的索引

    我有一个带有显示模板的 mvc 页面 如何获取显示模板中呈现的当前项目的索引 它在名称属性中产生正确的可绑定结果
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • 用于选择特定 div 中具有特定类的锚元素的 jQuery 选择器是什么

    我有一些这样的代码 我想选择每个 a 带有类的标签status在 div 中foo div a class status a div 你可以这样做 foo find status a
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么

随机推荐

  • 使用 AngularJS 在 Chrome 中中断变量更改

    如同this https stackoverflow com questions 11618278 how to break on property change in chrome问题 我想打破 Chrome 中的变量更改 但是 我使用的
  • 使用 chrome.history.deleteRange 未完全删除历史记录

    我写了一个小扩展 使用deleteRange from chrome historyAPI 用于删除开始时间戳和结束时间戳之间的部分浏览器历史记录 chrome history deleteRange startTime startTime
  • 使用C#正则表达式替换XML元素内容

    我正在编写一些处理记录 xml 数据的代码 并且我希望能够替换文档中某些元素 例如密码 的内容 我不想序列化和解析文档 因为我的代码将处理各种模式 输入文档示例 doc 1
  • 虚拟主机无法在 zend 框架中工作

    以下是我在 etc apache2 sites available 中的虚拟主机
  • 实体框架 6.1:字典中不存在给定的键

    我有一个带有一些关系的表 程序工作正常 直到我在该表和customer表 ddlPermissionCode表 第一表 如下 CREATE TABLE dbo PermissionCode Id int NOT NULL IDENTITY
  • Flutter 在选择时更改 TabItem 背景

    我想问一下 选择选项卡时如何更改选项卡项目背景颜色 抱歉 我是颤振的新手 使用底部标签栏还是标签栏更好 像这样 我的代码 bottomNavigationBar new TabBar tabs Tab icon new Icon Icons
  • 如何找到二维数组JAVA中元素的平均值? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我需要以下程序的帮助 编写一个方法 将二维双精度数组作为输入参数并返回数组元素的平均值 谁能告诉我该怎么做 我当前的代码 public
  • 通过 Slack API 发送命令

    有没有办法以编程方式发送command通过 API 到 Slack 我已成功发布消息 var postingResponse client UploadValues https slack com api chat postMessage
  • Android GPS 的准确度如何? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我好像在某处读过Android的GPS精度约为10厘米 任何人都可以验证或更正这个吗 原因是我正在尝试开发的应用程序会跟踪用户访问过的位置 这将极大地
  • 谷歌地图圆圈与标签

    我使用 google 地图 api 创建了地图视图 通过使用 google maps Circle 圆圈在地图上打印 将标记更改为圆圈 没有任何问题 但我无法在其中添加标签或文本 我该如何解决这个问题 这是我用来打印圆圈的代码 functi
  • 如何使用 fetch api 及其 javascript 加载 html 页面?

    我正在尝试使用 fetch API 加载 HTML 页面及其 JavaScript 脚本 我可以使用 ajax 和 JQuerySee here https stackoverflow com questions 50847274 fetc
  • NSUTF8StringEncoding 导致文件在 TextEdit/Pages 中渲染不正确,但在 BBEdit/vi 中则不会

    我遇到了一个有点奇怪的问题 每当我在 iOS 应用程序中创建新的文本文件时 我都会将其编码设置为NSUTF8StringEncoding 如果我编辑文件并输入任何带变音符号的字符并保存更改 则变音符号在某些应用程序 如 BBEdit Tex
  • 具有核心动画页面和长列表的聚合物芯片到卡图案

    一般来说 我发现很难使用core animated pages当我有一个滚动页面的很长列表时 聚合物元素可实现芯片列表到卡片类型模式 我认为困难在于 一旦过渡完成 隐藏部分就会从布局中取出 我很难找到解决这个问题的方法 简单的插图 JSFi
  • “Josephus-p‌r‌o‌b‌l‌e‌m” 在 python 中使用列表

    我想知道是否可以使用 python 中的列表来解决约瑟夫问题 简单来说 约瑟夫问题就是在圆形排列中找到一个位置 如果使用事先已知的跳过参数来处理执行 那么该位置将是安全的 例如 给定一个圆形排列 例如 1 2 3 4 5 6 7 并且ski
  • 无法使用 mailto uri 创建具有多个收件人的新邮件

    我正在使用创建一个Windows 8 1 应用商店 in WinRT 我无法通过用逗号或分号分隔每封电子邮件来使用 mailto uri 创建具有多个收件人的新邮件 两者都会给我相同的错误 Invalid URI The hostname
  • JUnit4 根据自定义 java 注释跳过测试

    我希望根据我用 Java 创建的自定义注释来执行 JUnit4 测试 此自定义注释的目的是让 JUnit4 注意到 仅当机器的平台与注释中指定的平台匹配时才应运行测试 假设我有以下注释 public interface Annotation
  • 在主程序.cs 文件中运行另一个 .cs 文件

    一般来说 我对编程很陌生 所以我确信这个问题很天真 因此 我编写了一个简单的神奇八球程序 我想转向冒险游戏 但我认为在游戏中包含八球程序会很简洁 就像制作一个控制台菜单 您可以在其中选择任一游戏 所以 我的问题是 我不知道如何将我的八球程序
  • 解析并获取 JSON 数据

    我有一个来自网站的 json 看起来像 Meta Data 1 Information Daily Prices open high low close and Volumes 2 Symbol MSFT 3 Last Refreshed
  • 以编程方式设计 GUI - 嵌套布局和多个小部件 (Qt) 的良好实践

    我有兴趣更好地理解Qt为此我想see 如何仅以编程方式完成嵌套布局和多个小部件 GUI 的相对复杂示例 即不使用 Qt Creator 的设计 我见过几个示例代码仅演示非常简单的布局 并且几乎总是不使用头文件 事实上我见过的大多数例子 du
  • Skip 的性能(以及类似功能,如 Take)

    我刚刚看了一下源代码Skip Take NET Framework 的扩展方法 在IEnumerable