当前位置: 首页 > news >正文

黄骅港信息吧windows优化大师好用吗

黄骅港信息吧,windows优化大师好用吗,中国建设银行手机银行下载官方网站,网页制作代码html大家在平时开发中大多都会遵循接口编程#xff0c;这样就可以方便实现依赖注入也方便实现多态等各种小技巧#xff0c;但这种是以牺牲性能为代价换取代码的灵活性#xff0c;万物皆有阴阳#xff0c;看你的应用场景进行取舍。一#xff1a;背景1. 缘由在项目的性能改造中这样就可以方便实现依赖注入也方便实现多态等各种小技巧但这种是以牺牲性能为代价换取代码的灵活性万物皆有阴阳看你的应用场景进行取舍。一背景1. 缘由在项目的性能改造中发现很多方法签名的返回值都是采用IEnumerable接口比如下面这段代码:public static void Main(string[] args){var list GetHasEmailCustomerIDList();foreach (var item in list){}Console.ReadLine();}public static IEnumerableint GetHasEmailCustomerIDList(){return Enumerable.Range(1, 5000000).ToArray();} 2. 有什么问题这段代码乍一看也没啥什么性能问题foreach迭代天经地义这个还能怎么优化1 从MSIL中寻找问题首先我们尽可能把原貌还原出来简化后的MSIL如下。 .method public hidebysig static void Main (string[] args) cil managed {IL_0009: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator1!0 class [mscorlib]System.Collections.Generic.IEnumerable1int32::GetEnumerator()IL_000e: stloc.1.try{IL_000f: br.s IL_001a// loop start (head: IL_001a)IL_0011: ldloc.1IL_0012: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator1int32::get_Current()IL_0017: stloc.2IL_0018: nopIL_0019: nopIL_001a: ldloc.1IL_001b: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()IL_0020: brtrue.s IL_0011// end loopIL_0022: leave.s IL_002f} // end .tryfinally{IL_0024: ldloc.1IL_0025: brfalse.s IL_002eIL_0027: ldloc.1IL_0028: callvirt instance void [mscorlib]System.IDisposable::Dispose()IL_002d: nopIL_002e: endfinally} // end handlerIL_002f: ret } // end of method Program::Main 从IL中看到了标准的get_Current,MoveNext,Dispose 还有一个try,finally一下子多了这么多方法和关键词不就是一个简单的foreach迭代数组嘛至于搞的这么复杂嘛这样在大数据下怎么快的起来还有一个奇葩的事如果你仔细观察IL代码比如这句[mscorlib]System.Collections.Generic.IEnumerable1int32::GetEnumerator(), 这个GetEnumerator前面是接口IEnumerable正常情况下应该是具体迭代类吧按理说应该会调用Array的GetEnumerator方法如下所示。[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中发现的第二个问题我特别好奇????????我们到托管堆上去看下到底是哪一个具体类调用了GetEnumerator()方法。!clrstack -l !do xx 到线程栈上抓list变量 0:000 !clrstack -l 000000229e3feda0 00007ff889e40951 *** WARNING: Unable to verify checksum for ConsoleApp2.exe ConsoleApp2.Program.Main(System.String[]) [C:\dream\Csharp\ConsoleApp1\ConsoleApp2\Program.cs 32]LOCALS:0x000000229e3fede8 0x0000019bf33b9a880x000000229e3fede0 0x0000019be33b2d900x000000229e3fedfc 0x00000000004c4b400:000 !do 0x0000019be33b2d90 Name: System.SZArrayHelperSZGenericArrayEnumerator1[[System.Int32, mscorlib]] MethodTable: 00007ff8e8d36d18 EEClass: 00007ff8e7cf5640 Size: 32(0x20) bytes File: C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll Fields:MT Field Offset Type VT Attr Value Name 00007ff8e7a98538 4002ffe 8 System.Int32[] 0 instance 0000019bf33b9a88 _array 00007ff8e7a985a0 4002fff 10 System.Int32 1 instance 5000000 _index 00007ff8e7a985a0 4003000 14 System.Int32 1 instance 5000000 _endIndex 00007ff8e8d36d18 4003001 0 ...Int32, mscorlib]] 0 shared static Empty Domain:Value dynamic statics NYI 0000019be1893a80:NotInit 居然有这么一个类型 Name: System.SZArrayHelperSZGenericArrayEnumerator然来是JIT捣的鬼生成了这么一个SZGenericArrayEnumerator类型接下来把它的方法表打出来看看里面都有啥方法。 0:000 !dumpmt -md 00007ff8e8d36d18 EEClass: 00007ff8e7cf5640 Module: 00007ff8e7a71000 Name: System.SZArrayHelperSZGenericArrayEnumerator1[[System.Int32, mscorlib]] mdToken: 0000000002000a98 File: C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll BaseSize: 0x20 ComponentSize: 0x0 Slots in VTable: 11 Number of IFaces in IFaceMap: 3 -------------------------------------- MethodDesc TableEntry MethodDesc JIT Name 00007ff8e7ff2450 00007ff8e7a78de8 PreJIT System.Object.ToString() 00007ff8e800cc60 00007ff8e7c3b9b0 PreJIT System.Object.Equals(System.Object) 00007ff8e7ff2090 00007ff8e7c3b9d8 PreJIT System.Object.GetHashCode() 00007ff8e7fef420 00007ff8e7c3b9e0 PreJIT System.Object.Finalize() 00007ff8e8b99fd0 00007ff8e7ebf388 PreJIT System.SZArrayHelperSZGenericArrayEnumerator1[[System.Int32, mscorlib]].MoveNext() 00007ff8e8b99f90 00007ff8e7ebf390 PreJIT System.SZArrayHelperSZGenericArrayEnumerator1[[System.Int32, mscorlib]].get_Current() 00007ff8e8b99f60 00007ff8e7ebf398 PreJIT System.SZArrayHelperSZGenericArrayEnumerator1[[System.Int32, mscorlib]].System.Collections.IEnumerator.get_Current() 00007ff8e8b99f50 00007ff8e7ebf3a0 PreJIT System.SZArrayHelperSZGenericArrayEnumerator1[[System.Int32, mscorlib]].System.Collections.IEnumerator.Reset() 00007ff8e8b99f40 00007ff8e7ebf3a8 PreJIT System.SZArrayHelperSZGenericArrayEnumerator1[[System.Int32, mscorlib]].Dispose() 00007ff8e8b99ef0 00007ff8e7ebf3b0 PreJIT System.SZArrayHelperSZGenericArrayEnumerator1[[System.Int32, mscorlib]]..cctor() 00007ff8e8b99ff0 00007ff8e7ebf380 PreJIT System.SZArrayHelperSZGenericArrayEnumerator1[[System.Int32, mscorlib]]..ctor(Int32[], Int32) 可以看到这是一个标准的迭代类这性能又被拖累了。。。二优化性能综合上面分析貌似问题出在了 foreach 和 IEnumerableint这两个方面。1. IEnumerable 替换 int[] foreach改成for知道了这两点接下来把代码修改如下 public static void Main(string[] args){var list GetHasEmailCustomerIDList();for (int i 0; i list.Length; i) { }Console.ReadLine();}public static int[] GetHasEmailCustomerIDList(){return Enumerable.Range(1, 5000000).ToArray();}.method public hidebysig static void Main (string[] args) cil managed {// (no C# code)IL_0000: nop// int[] hasEmailCustomerIDList GetHasEmailCustomerIDList();IL_0001: call int32[] ConsoleApp2.Program::GetHasEmailCustomerIDList()IL_0006: stloc.0// for (int i 0; i hasEmailCustomerIDList.Length; i)IL_0007: ldc.i4.0IL_0008: stloc.1// (no C# code)IL_0009: br.s IL_0011// loop start (head: IL_0011)IL_000b: nopIL_000c: nop// for (int i 0; i hasEmailCustomerIDList.Length; i)IL_000d: ldloc.1IL_000e: ldc.i4.1IL_000f: addIL_0010: stloc.1// for (int i 0; i hasEmailCustomerIDList.Length; i)IL_0011: ldloc.1IL_0012: ldloc.0IL_0013: ldlenIL_0014: conv.i4IL_0015: cltIL_0017: stloc.2IL_0018: ldloc.2// (no C# code)IL_0019: brtrue.s IL_000b// end loop// Console.ReadLine();IL_001b: call string [mscorlib]System.Console::ReadLine()// (no C# code)IL_0020: pop// }IL_0021: ret } // end of method Program::Main 可以看到上面的IL指令都是非常基础的指令大多都有CPU指令直接提供支持非常简洁大爱~~~这里有一点要注意我后来观察foreach不需要改成forvs编辑器在底层帮我们转换了看的出来foreach在迭代数组类型的时候还是非常智能的知道怎么帮助我们优化。。。修改代码如下public static void Main(string[] args){var list GetHasEmailCustomerIDList();//for (int i 0; i list.Length; i) { }foreach (var item in list) { }Console.ReadLine();}.method public hidebysig static void Main (string[] args) cil managed {// (no C# code)IL_0000: nop// int[] hasEmailCustomerIDList GetHasEmailCustomerIDList();IL_0001: call int32[] ConsoleApp2.Program::GetHasEmailCustomerIDList()IL_0006: stloc.0// (no C# code)IL_0007: nop// int[] array hasEmailCustomerIDList;IL_0008: ldloc.0IL_0009: stloc.1// for (int i 0; i array.Length; i)IL_000a: ldc.i4.0IL_000b: stloc.2// (no C# code)IL_000c: br.s IL_0018// loop start (head: IL_0018)// int num array[i];IL_000e: ldloc.1IL_000f: ldloc.2IL_0010: ldelem.i4// (no C# code)IL_0011: stloc.3IL_0012: nopIL_0013: nop// for (int i 0; i array.Length; i)IL_0014: ldloc.2IL_0015: ldc.i4.1IL_0016: addIL_0017: stloc.2// for (int i 0; i array.Length; i)IL_0018: ldloc.2IL_0019: ldloc.1IL_001a: ldlenIL_001b: conv.i4IL_001c: blt.s IL_000e// end loop// Console.ReadLine();IL_001e: call string [mscorlib]System.Console::ReadLine()// (no C# code)IL_0023: pop// }IL_0024: ret } // end of method Program::Main 2. 代码测试微观方面已经带大家分析过了接下来宏观测试两种方式的性能到底相差多少每一个方法我都做10次性能对比。 public static void Main(string[] args){var arr GetHasEmailCustomerIDArray();for (int i 0; i 10; i){var watch Stopwatch.StartNew();foreach (var item in arr) { }watch.Stop();Console.WriteLine($i{i},时间:{watch.ElapsedMilliseconds});}Console.WriteLine(---------------);var list arr as IEnumerableint;for (int i 0; i 10; i){var watch Stopwatch.StartNew();foreach (var item in list) { }watch.Stop();Console.WriteLine($i{i},时间:{watch.ElapsedMilliseconds});}Console.ReadLine();}public static int[] GetHasEmailCustomerIDArray(){return Enumerable.Range(1, 5000000).ToArray();}i0,时间:10 i1,时间:10 i2,时间:10 i3,时间:9 i4,时间:9 i5,时间:9 i6,时间:10 i7,时间:10 i8,时间:12 i9,时间:12 --------------- i0,时间:45 i1,时间:37 i2,时间:35 i3,时间:35 i4,时间:37 i5,时间:35 i6,时间:36 i7,时间:37 i8,时间:35 i9,时间:36 难以置信的是居然有3-4倍的差距。。。这就是用灵活性换取性能的代价????????????好了本篇就说到这里希望对你有帮助。
http://www.zqtcl.cn/news/369870/

相关文章:

  • 上海网站建设网络推广网页搜索框下记录删不掉
  • 团购网站大全做相册手机网站如何制作免费
  • 承德网站制作方案百度seo关键词排名s
  • 网站建设公司佛山国内网站推广
  • 辽宁网站制作公司潍坊网站建设维护
  • 手机网站图片切换平面图网站
  • 松岗建设网站广州网站定制开发方案
  • 东阳网站建设价格做理财的网站有哪些问题
  • 蓄电池回收网站建设wordpress cp 部署
  • cuteftp 备份网站网站制作课程介绍
  • 杭州网站搭建宁波企业官网建设
  • php免费网站源码网站建设电子书
  • 建设纺织原料网站专业网页制作室
  • 买域名做网站推广都是些什么湘潭什么网站做c1题目
  • 鲜花网站建设图片昆明网站建站平台
  • 密云网站制作案例昆明小程序开发
  • 网站紧急维护商丘手机网站制作
  • 什么专业会制作网站罗湖做网站的公司哪家好
  • 永久免费ppt下载网站有没有跟一起做网店一样的网站
  • 百川网站石家庄物流网站建设
  • 广州外贸网站设计外贸seo外贸推广外贸网站建设外贸网站建设
  • 网站 栏目建设银行网站用户名是什么
  • 服装类的网站建设中原免费网站建设
  • 网站开发培训班多少报名费安徽省建设工程信息网站
  • 旅游网站规划设计余姚网站公司
  • 广州市地铁站地图dede增加手机网站
  • dede 网站名称 空的网站开发行业新闻
  • 网站开发费用做账升级系统
  • 外贸公司网站制作价格网络公司的经营范围有哪些
  • 东莞三合一网站制作海南省生态文明村建设促进会网站