博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 性能优化之斤斤计较篇 二
阅读量:6463 次
发布时间:2019-06-23

本文共 3140 字,大约阅读时间需要 10 分钟。

接继续,本文的完整源代码也在上篇文章中。

枚举数组和普通枚举性能差异

有些人可能知道,.net在处理枚举时,对于数组有特别的优化,所以,当枚举的集合是一个数组时,性能会好些。例如下面的测试代码:

1     class C1 { 2  3         public void Do1() { 4             int[] array = { 1, 2, 3, 4 }; 5             for (int i = 0; i < int.MaxValue/100; i++) { 6                 DoIt1(array); 7             } 8         } 9 10         private void DoIt1
(IEnumerable
array) {11 foreach (var item in array) {12 13 }14 }15 16 public void Do2() {17 int[] array = { 1, 2, 3, 4 };18 for (int i = 0; i < int.MaxValue/100; i++) {19 DoIt2(array);20 }21 }22 23 private void DoIt2(int[] array) {24 foreach (var item in array) {25 26 }27 }28 }

 

第23行的方法中,编译器提前已知是一个数组的枚举,所以会优化指令。那么,到底这种优化差距有多大呢?我需要试验一下。

第一个是Do1的结果,第二个是Do2的结果,显而易见,差距还是相当大的,为什么呢?从反编译的IL代码来看,第一个方法使用标准的GetEnumerator机制,需要创建实例,而且要调用Current和MoveNext两个方法,更何况,Array的GetValue实现实在不够快。而第二个方法使用了for的机制,无需创建实例,不断累加和一个判断语句即可,性能当然高了。

在Linq to Object中,其实是有这样考虑的代码的。例如:

public static IEnumerable
Select
(this IEnumerable
source, Func
selector){ if (source == null) { throw Error.ArgumentNull("source"); } if (selector == null) { throw Error.ArgumentNull("selector"); } if (source is Enumerable.Iterator
) { return ((Enumerable.Iterator
)source).Select
(selector); } if (source is TSource[]) { return new Enumerable.WhereSelectArrayIterator
((TSource[])source, null, selector); } if (source is List
) { return new Enumerable.WhereSelectListIterator
((List
)source, null, selector); } return new Enumerable.WhereSelectEnumerableIterator
(source, null, selector);}

 

 

创建类和结构的性能差异以及属性和字段的性能差异

下面我还要试验创建类实例和结构类型,其性能差异到底有多大?会不会.net的垃圾回收超级厉害,基本上差异不大呢?当然,我也顺手测试了访问属性和访问字段的差别。

1     class C1 { 2         public void Do1() { 3             for (int i = 0; i < int.MaxValue/10; i++) { 4                 var p = new PointClass() { X = 1, Y = 2 }; 5             } 6         } 7         public void Do2() { 8             for (int i = 0; i < int.MaxValue/10 ; i++) { 9                 var p = new PointClass2() { X = 1, Y = 2 };10             }11         }12         public void Do3() {13             for (int i = 0; i < int.MaxValue/10; i++) {14                 var p = new Point() { X = 1, Y = 2 };15             }16         }17         public void Do4() {18             for (int i = 0; i < int.MaxValue / 10; i++) {19                 var p = new Point() { XP = 1, YP = 2 };20             }21         }22     }23 24 25     class PointClass {26         public int X { get; set; }27         public int Y { get; set; }28     }29 30     class PointClass2 {31         public int X;32         public int Y;33     }34 35     struct Point {36         public int X;37         public int Y;38 39         public int XP { get { return X; } set { X = value; } }40         public int YP { get { return Y; } set { Y = value; } }41     }

 

测试结果如下:

实验结果表明:在计算密集型的程序中,结构的创建仍然比类要高效的多,另外,属性和字段的访问其性能基本相当。

转载地址:http://hxhzo.baihongyu.com/

你可能感兴趣的文章
SoapUI中如何传递cookie
查看>>
静态成员变量的初始化
查看>>
POJ 1269 Intersecting Lines(判断两直线位置关系)
查看>>
MSSQL数据库跨表和跨数据库查询方法简(转)
查看>>
spring3.0.7中各个jar包的作用总结
查看>>
Windows 10 /win10 上使用GIT慢的问题,或者命令行反应慢的问题
查看>>
SSM——查询_分页
查看>>
梯度下降(Gradient descent)
查看>>
Windows平台分布式架构实践 - 负载均衡
查看>>
如何让LinearLayout也有类似Button的点击效果?
查看>>
JAVA读取文件方法大全
查看>>
寻找最小的k个数
查看>>
CSS3中的动画效果记录
查看>>
CI框架整合微信公共平台接口
查看>>
request.getScheme()的使用方法
查看>>
Android快速开发常用知识点系列目录
查看>>
Java ActiveMQ队列模式案例
查看>>
EJB2的配置
查看>>
最容易理解的对卷积(convolution)的解释
查看>>
《机器学习实战》知识点笔记目录
查看>>