开发者社区> 范大脚脚> 正文

【译】使用C# yield关键字来提高性能和可读性

简介:
+关注继续查看
对于”yield”这个关键字我已经见过N次了,直到最近我才知道这个关键字所蕴含的力量。我将在下面展示出一些使用”yield”让你的代码有更高可读性和更好性能的例子.

 

为了让你对yield有一些快速概览,我首先要展示一个没有使用这个关键字的例子,下面的代码很简单,但在我最近的项目中却很常见

IList<string> FindBobs(IEnumerable<string> names)
{
var bobs = new List<string>();

foreach(var currName in names)
{
if(currName == "Bob")
bobs.Add(currName);
}

return bobs;
}
注意在这里我使用IEnumerable<string>作为参数类型并以IList<string>作为返回类型,通常来说,我更倾向于在参数输入的类型方面的范围越宽越好,但在返回类型上面更加严格(译者按:即输入时多用基类或接口,返回时用子类或实现类),对于输入来说,如果你需要用foreach来对其进行循环的话,使用IEnumerable会更有意义。而对于输出(译者按:也就是返回),我使用接口来让实现部分可以改变。在这里我想让调用者省去生成列表的麻烦,所以我选择list作为返回类型.

 

而问题在于,我的设计并不具有可链接性,这样的设计需要产生列表作为返回值,实现上,这个列表或许不会很大,但这并不必要


现在,让我们来看看以“yield”的方式来做这些,而后我会解释如何使用它,以及它工作的原理。

IEnumerable<string> FindBobs(IEnumerable<string> names)
{
foreach(var currName in names)
{
if(currName == "Bob")
yield return currName;
}
}
在这个版本中,我们将返回类型改为IEnumerable,并且我们使用”yield return”.注意我再也不需要创建一个列表,现在是不是有些迷惑的?别着急,在理解它的工作方式的情况它会变的越来越简单.

当使用”yield return”关键词组时,.net会为你生成一大串管道代码,你可以尽管假装这是个魔法。当开始在被调用的代码中循环时(这里不是list),实现上发生的是这个函数被一遍一遍的调用,但每一次都从上一次执行退出的部分开始继续执行.

 

传统的执行方法

调用函数
函数执行并返回list
调用部分使用返回的list
Yield的执行方法

调用函数
调用者请求item
下一个item返回
回到步骤2
虽然yield执行的实现貌似有些复杂,但我们最终只需要一次“弹出”一个item,而不是创建整个list并返回.

对于句法说,我个人认为yield更加简洁,并且对于传递函数的用途表现的更好(译者按:也就是代码可读性),我使用IEnumerable作为返回类型来通知调用者它可以被foreach循环并且返回数据,而调用者现在可以自己决定它是否愿意将返回值存放到列表中,即使这会以性能作为代价。

在我提供的这个简单例子中,也许你并不能发现很多使用yield的好处,然而,你可以在调用者需要取消遍历所有的函数提供的内容时节省很多不必要的工作,当你在方法链接时使用yield,你可以省下的工作(时间)或许会成倍叠加。

Ayende已经有了很棒的例子:using yield for a slick pipes & filters implementation,他甚至还讲述了:version that is multi-threaded。这让我觉得非常有趣.

最开始我对yield的保留意见是使用这个关键字或许会导致潜在的性能问题,但实际上,至今为止我还未能发现任何信息来说明关于yield对性能的影响,而我在上面提到提高性能的地方远远大于编译器overhead那部分。

 

小结
Yield可以让你的代码更加高效并拥有更高的可读性,已经是.net 2.0时代了,我想已经没有什么借口可以阻止我们学习和使用yield.

---------------------------------------------------------------------

译者:这篇文章是我翻译的十个鲜为人知的C#关键字里的pangxiaoliang[北京]流浪者同学在评论中提出的意见,那篇文章只是做了个总结,我发现已经有关于论述更深层次的好文了,所以我就不重复发明轮子直接进行翻译了,在翻译的过程中我也学到了不少.谢谢

原文链接:http://www.ytechie.com/2009/02/using-c-yield-for-readability-and-performance.html



本文转自CareySon博客园博客,原文链接:http://www.cnblogs.com/CareySon/archive/2009/12/16/1625469.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
SLB高性能与高可用技术实践全解析
云栖社区2017在线技术峰会上,阿里云刺背分享了双十一以及红包期间SLB关于高性能、高可用性方面做的一些技术改进。他详细介绍了软件负载均衡SLB及其部署,从系统架构方面介绍了高性能的负载均衡技术,从后端服务器、可用区内、可用区间三个方面介绍了高可用的负载均衡技术。
5957 0
C# defualt关键字默认值用法
原文:C# defualt关键字默认值用法 默认值表达式生成类型的默认值。 默认值表达式在泛型类和泛型方法中非常有用。 使用泛型类和泛型方法时出现的一个问题是,如何在无法提前知道以下内容的情况下将默认值赋值给参数化类型 T: T 是引用类型还是值类型。
791 0
分布式系统架构中高可用方案技术选型:Hystrix 框架实现服务保护使用详解
本篇文章介绍了分布式系统架构下的经典的高可用框架Hsytrix实现的断路器,服务降级,服务熔断,服务隔离以及解决服务雪崩效应的问题。详细分析了基于Hystrix框架解决分布式系统中服务雪崩效应的几种机制,以及在项目中如何集成Hystrix框架并且在项目中使用Hystrix框架实现分布式系统中的服务治理。
319 0
使用c#制作网络爬虫,检查站点可访问性
  前几天自己负责的网站出现了不能访问的问题,系统监控程序通过告警将这一信息告诉了管理员。管理员找到了我,告诉我站点不能正常访问。后来问题查明,是负载均衡器出了问题。自己在检查站点的时候,发现有些图片不能正确显示,原因是图片链接无效。
771 0
C# 基础知识 protected 关键字
using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace ConsoleApplication1{    public class A    {        pro...
524 0
带你读《点石成金:访客至上的Web和移动可用性设计秘笈》之二:我们实际上是如何使用Web的
这是一本关于Web设计原则而不是Web设计技术的书。本书作者是Web设计专家,具有丰富的实践经验,他用幽默的语言为你揭示Web设计中重要但却容易被忽视的问题,只需几个小时,你便能对照书中讲授的设计原则找到网站设计的症结所在,令你的网站焕然一新。
1117 0
《C语言编程初学者指南》一1.4 理解关键字
本节书摘来自华章出版社《C语言编程初学者指南》一书中的第1章,第1.4节,作者【美】Keith Davenport(达文波特) , M1ichael Vine(维恩),更多章节内容可以访问云栖社区“异步社区”公众号查看 1.4 理解关键字 在标准ANSI C编程语言中,有32个单词定义为关键字(keyword)。
1286 0
MySQL Fabric使用介绍01——高可用性HA
MySQL Fabric使用介绍01——高可用性HA   MySQL Fabric是MySQL推出的用来管理一“群”服务器的系统,可以非常简单地用来部署管理MySQL的数据分片(Shading)和高可用性(High Availability)功能。
1187 0
+关注
3656
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载