当前位置:首页 > 科技  > 软件

面向接口编程,你考虑过性能吗?

来源: 责编: 时间:2023-10-06 19:20:32 369观看
导读大家在平时开发中大多都会遵循接口编程,这样就可以方便实现依赖注入也方便实现多态等各种小技巧,但这种是以牺牲性能为代价换取代码的灵活性,万物皆有阴阳,看你的应用场景进行取舍。一:背景1. 缘由在项目的性能改造中,发现

大家在平时开发中大多都会遵循接口编程,这样就可以方便实现依赖注入也方便实现多态等各种小技巧,但这种是以牺牲性能为代价换取代码的灵活性,万物皆有阴阳,看你的应用场景进行取舍。I6q28资讯网——每日最新资讯28at.com

一:背景

1. 缘由

在项目的性能改造中,发现很多方法签名的返回值都是采用IEnumerable接口,比如下面这段代码:I6q28资讯网——每日最新资讯28at.com

public static void Main(string[] args)        {            var list = GetHasEmailCustomerIDList();            foreach (var item in list){}             Console.ReadLine();        }        public static IEnumerable<int> GetHasEmailCustomerIDList()        {            return Enumerable.Range(1, 5000000).ToArray();        }

2. 有什么问题

这段代码乍一看也没啥什么性能问题,foreach迭代天经地义,这个还能怎么优化???I6q28资讯网——每日最新资讯28at.com

<1> 从MSIL中寻找问题

首先我们尽可能把原貌还原出来,简化后的MSIL如下。I6q28资讯网——每日最新资讯28at.com

.method public hidebysig static     void Main (        string[] args    ) cil managed{    IL_0009: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()    IL_000e: stloc.1    .try    {        IL_000f: br.s IL_001a        // loop start (head: IL_001a)            IL_0011: ldloc.1            IL_0012: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()            IL_0017: stloc.2            IL_0018: nop            IL_0019: nop            IL_001a: ldloc.1            IL_001b: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()            IL_0020: brtrue.s IL_0011        // end loop        IL_0022: leave.s IL_002f    } // end .try    finally    {        IL_0024: ldloc.1        IL_0025: brfalse.s IL_002e        IL_0027: ldloc.1        IL_0028: callvirt instance void [mscorlib]System.IDisposable::Dispose()        IL_002d: nop        IL_002e: endfinally    } // end handler    IL_002f: ret} // end of method Program::Main

从IL中看到了标准的get_Current,MoveNext,Dispose 还有一个try,finally,一下子多了这么多方法和关键词,不就是一个简单的foreach迭代数组嘛?至于搞的这么复杂嘛?这样在大数据下怎么快的起来?I6q28资讯网——每日最新资讯28at.com

还有一个奇葩的事,如果你仔细观察IL代码,比如这句:[mscorlib]System.Collections.Generic.IEnumerable``1<int32>::GetEnumerator(), 这个GetEnumerator前面是接口IEnumerable,正常情况下应该是具体迭代类吧,按理说应该会调用Array的GetEnumerator方法,如下所示。I6q28资讯网——每日最新资讯28at.com

[Serializable][ComVisible(true)][__DynamicallyInvokable]public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable{    [__DynamicallyInvokable]    public IEnumerator GetEnumerator()    {        int lowerBound = GetLowerBound(0);        if (Rank == 1 && lowerBound == 0)        {            return new SZArrayEnumerator(this);        }        return new ArrayEnumerator(this, lowerBound, Length);    }}

<2> 从windbg中寻找问题

IL中发现的第二个问题我特别好奇,

本文链接:http://www.28at.com/showinfo-26-12145-0.html面向接口编程,你考虑过性能吗?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: SpringBoot项目部署轻松变Docker,原来只需这几步!

下一篇: 数据安全之道:Java加密技术保护MySQL数据库

标签:
  • 热门焦点
  • 5月iOS设备性能榜:M1 M2依旧是榜单前五

    和上个月一样,没有新品发布的iOS设备性能榜的上榜设备并没有什么更替,仅仅只有跑分变化而产生的排名变动,刚刚开始的苹果WWDC2023,推出的产品也依旧是新款Mac Pro、新款Mac Stu
  • K6:面向开发人员的现代负载测试工具

    K6 是一个开源负载测试工具,可以轻松编写、运行和分析性能测试。它建立在 Go 和 JavaScript 之上,它被设计为功能强大、可扩展且易于使用。k6 可用于测试各种应用程序,包括 Web
  • 得物效率前端微应用推进过程与思考

    一、背景效率工程随着业务的发展,组织规模的扩大,越来越多的企业开始意识到协作效率对于企业团队的重要性,甚至是决定其在某个行业竞争中突围的关键,是企业长久生存的根本。得物
  • 只需五步,使用start.spring.io快速入门Spring编程

    步骤1打开https://start.spring.io/,按照屏幕截图中的内容创建项目,添加 Spring Web 依赖项,并单击“生成”按钮下载 .zip 文件,为下一步做准备。请在进入步骤2之前进行解压。图
  • Python异步IO编程的进程/线程通信实现

    这篇文章再讲3种方式,同时讲4中进程间通信的方式一、 Python 中线程间通信的实现方式共享变量共享变量是多个线程可以共同访问的变量。在Python中,可以使用threading模块中的L
  • 网红炒股不为了赚钱,那就是耍流氓!

    来源:首席商业评论6月26日高调宣布入市,网络名嘴大v胡锡进居然进军了股市。在一次财经媒体峰会上,几个财经圈媒体大佬就&ldquo;胡锡进炒股是否知道认真报道&rdquo;展开讨论。有
  • 三星电子Q2营收60万亿韩元 存储业务营收同比仍下滑超过50%

    7月27日消息,据外媒报道,从三星电子所发布的财报来看,他们主要利润来源的存储芯片业务在今年二季度仍不乐观,营收同比仍在大幅下滑,所在的设备解决方案
  • iQOO Neo8系列新品发布会

    旗舰双芯 更强更Pro
  • 苹果MacBook Pro 2021测试:仍不支持平滑滚动

    据10月30日9to5 Mac 消息报道,苹果新的 14 英寸和 16 英寸 MacBook Pro 2021 上市后获得了不错的评价,亮点包括行业领先的性能,令人印象深刻的电池续航,精美丰
Top