C# 代码优化 性能优化【转】

摘要:
代码的优化有助于让程序运行速度更快一些。C#代码优化拾贝1、Float并不比Double要快软件测试和优化工作的一个重要原则是以实验为基础,一切以实验结果为准;我曾想当然的认为Float类型的位数少,理所当然应该比Double类型运算的要快。

自己所作的项目中开始慢慢接触到程序的优化部分,慢慢的对这些有了很多的理解。代码的书写规范化有助于团队中成员对你代码快速的理解。代码的优化有助于让程序运行速度更快一些。所以如下特转一些文字说明和本人的一些愚见。

C#代码优化拾贝

1、Float并不比Double要快

软件测试和优化工作的一个重要原则是以实验为基础,一切以实验结果为准;我曾想当然的认为Float类型的位数少,理所当然应该比Double类型运算的要快。然而实验证明,这种想法是错误的;

考察如下代码的速度:

int i,j;

float f1=7.125f,f2=7.125f;

double d1=7.125d,d2=7.125d;

DateTime dt = DateTime.Now;

for ( i = 0; i < 1000000000; i++ )

{

f1 = f2 / 2.2f +12.3333f;

}

TimeSpan ts = DateTime.Now - dt;

MessageBox.Show ( ts.ToString() );

dt = DateTime.Now;

for ( i = 0; i < 1000000000; i++ )

{

d1 = d2 / 2.2d +12.3333d;

}

ts = DateTime.Now - dt;

MessageBox.Show(ts.ToString());

运行这段代码,得到的结论是,Float类型和Double类型的运算速度完全一样;由此可见,如果把Double 类型换成Float,程序的速度不会有任何提升;

如果仅仅是这样,我们还可以接受Float,因为毕竟Float比较省内存;

然而,Float很不争气,我发现了他的一个致命弱点,把Float转化成int花费的时间太长了,比把Double类型转成整形所花费的时间多了一倍;

想要验证这点的话,把刚才的代码改成这样:

int i,j;

float f1=7.125f,f2=7.125f;

double d1=7.125d,d2=7.125d;

DateTime dt = DateTime.Now;

for ( i = 0; i < 1000000000; i++ )

{

//f1 = f2 / 2.2f +12.3333f;

j = (int)f1;

}

TimeSpan ts = DateTime.Now - dt;

MessageBox.Show ( ts.ToString() );

dt = DateTime.Now;

for ( i = 0; i < 1000000000; i++ )

{

//d1 = d2 / 2.2d +12.3333d;

j = (int)d1;

}

ts = DateTime.Now - dt;

MessageBox.Show(ts.ToString());

在我们的组态元件的代码中,到处都是浮点转整形的运算(因为计算机图形需要光栅化,所以象素点坐标必须是整数),因此,如果我们使用Float类型的话,代码恐怕会非常的慢;

2、右移和预计算优化是有效的

如今网络上有一种呼声,说现在的编译器足够智能,会对代码自动地进行一些常见的优化,一些老的优化方法已经不再适用了,比如用右移代替除法运算、预计算等等;

很可惜,如今的C# 虽然具有一些编译优化的功能,但还不象网络上所传颂的智能编译器那样的智能,经过实验发现,用右移代替除法运算、预计算等等技巧显然并未过时;

经过实验发现:对于整形来说,右移一位确实比除以2要快一些,大约快了 6%。

至 于预计算,经过实验发现,表达式的写法影响了C# 的预计算功能,比如,i=j*(2d/3d)编译器就可以对其进行优化,编译的时候,编译器会先求出2d/3d的值,然后把结果0.66…编译到目标代码 中,所以实际编译的代码等价于i=j*0.66…;而如果是 i=j*2d/3d ,编译器不会对其进行优化,所以,虽然两式运算结果完全相同,但是运算速度却是大相径庭;

如果充分的利用预计算功能,可以极大的提高代码执行速度,比如,角度转弧度的运算,是把角度先乘以圆周率然后除以180。通常按照自然习惯,会这样写 j = k * Math.PI / 180.0;

上式的写法显然没有利用到C#的预计算功能,而如果改成下式:
j = k * (Math.PI / 180.0);
就会发现,性能提高非常明显,大约快了70%;

3、减少冗余计算

优化前的代码如下所示,这是一个旋转点的函数,其中Sin(Angle),Cos(Angle)都各运算了两次,因此存在冗余计算。

private Point RotatePt(double angle, Point pt)

{

Point pRet = new Point();

angle = -angle;

pRet.X = (int)((double)pt.X * Math.Cos(angle) - (double)pt.Y * Math.Sin(angle));

pRet.Y = (int)((double)pt.X * Math.Sin(angle) + (double)pt.Y * Math.Cos(angle));

return pRet;
}

优化的代码的方法就是消除冗余计算,优化后的代码如下:

private Point RotatePt3(double angle, Point pt)

{

Point pRet = new Point();

angle = -angle;

double SIN_ANGLE = Math.Sin(angle);

double COS_ANGLE = Math.Cos(angle);

pRet.X =(int)(pt.X * COS_ANGLE - pt.Y * SIN_ANGLE);

pRet.Y = (int)(pt.X * SIN_ANGLE + pt.Y * COS_ANGLE);

return pRet;

}

优化后的代码,Sin(Angle),Cos(Angle)都只运算了一次,是“一次计算、两处使用”,性能提升大约30%

如果想再进一步优化,可以去掉临时变量pRet,总体性能还能提升大约 5%,代码如下:

private Point RotatePt(double angle, Point pt)

{

angle = -angle;

double SIN_ANGLE = Math.Sin(angle);

double COS_ANGLE =Math.Cos (angle);

return new Point((int)(pt.X * COS_ANGLE - pt.Y * SIN_ANGLE),

(int)(pt.X * SIN_ANGLE + pt.Y * COS_ANGLE));

}

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/qiqi5521/archive/2006/12/20/1450609.aspx

本人愚见

string ax=string.Empty;
注:不要使用: string ax="";判断ax是否为空:
ax.Length==0的效率要高于ax==string.Empty,但我一般做的是ax.IsNullorEmpty

对于不用改变的“变量”,记得用常量声明。

尽量用foreach代替for循环,我记得在哪里看到过,foreach的运行花费时间是for的1/3,有待考证。还有就是循环体里面尽量不要写判断语句,因为会影响效率,毕竟你循环一次,程序就做一次判断,这样就有N次循环N次判断,效率大打折扣。

记 住,在for循环中,很多人喜欢for(int i=0;i<xxx.Length;i++){},最好可以把xxx.Length存入一个变量中,然后带入for循环,因为每次判断都会去读取 xxx.Length值,这样无形中就浪费了时间,虽然智能的编译器会帮你完成这些,但最好你能明白这些。也请尽量别在循环内进行声明变量或初始化。

对于IDisposed接口的,一般要记得用完就释放,所以嘛,一般声明的时候我就用using(XXXXX xx=new XXXXX){Your Code}

vs2008里面可以使用类似于JavaScript的var类型,不过var是强类型,在编译的前就已经编译成了你所希望的类型,不至于影响你的速度。

对于字段和属性,字段访问的速度要快于属性。

linq是个好东西,linq to object中,用linq解决问题很快,不过调试的时候很烦

免责声明:文章转载自《C# 代码优化 性能优化【转】》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ESP32:mdns协议博客园样式美化(背景图片、公告栏头像、看板娘、鼠标特效、网易云音乐)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

9个小技巧让你的 if else看起来更优雅

if else 是我们写代码时,使用频率最高的关键词之一,然而有时过多的 if else 会让我们感到脑壳疼,例如下面这个伪代码: 是不是很奔溃?虽然他是伪代码,并且看起来也很夸张,但在现实中,当我们无数次 review 别人代码时,都会发现类似的场景,那么我们本文就来详细聊聊,有没有什么方法可以让我们避免来写这么多的 if else 呢? 我们本文提供了...

内存拷贝的优化方法

在复杂的底层网络程序中,内存拷 贝、字符串比较和搜索操作很容易成为性能瓶颈所在。编译器自带的此类函数虽然做了一些通用性的优化工作,但因为在使用指令集方面受到兼容性的约束,远远没 有达到最大限度利用硬件能力的地步。而通过针对特定硬件平台的优化,可以大大提高此类操作的性能。下面我将以P4平台下内存拷贝操作为例,根据AMD提供 的一份优化文档中的例子,简要介绍一...

Tomcat多实例集群架构 安全优化和性能优化

Tomcat多实例 复制tomcat目录 #将tar解压出来的tomcat复制出两个实例来cp -a /usr/local/apache-tomcat-8.0.46 /usr/local/tomcat1 cp -a /usr/local/apache-tomcat-8.0.46 /usr/local/tomcat2 修改多实例配置文件 #创建多实例的网页根...

Spark记录-Spark性能优化解决方案

Spark性能优化的10大问题及其解决方案 问题1:reduce task数目不合适解决方式:需根据实际情况调节默认配置,调整方式是修改参数spark.default.parallelism。通常,reduce数目设置为core数目的2到3倍。数量太大,造成很多小任务,增加启动任务的开销;数目太少,任务运行缓慢。 问题2:shuffle磁盘IO时间长...

Sql Server查询性能优化之走出索引的误区

据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会、也什么没有必要去关心、了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是,或者干脆把整个查询SQL直接发给DBA,让DBA直接帮忙优化了,所以造成的状况就是开发人员对于索引的理解、认识很局限,以下就把我个人对于索引的理解及浅薄认识...

ORB-SLAM3 单目地图初始化(终结篇)

作者: 乔不思 来源:微信公众号|3D视觉工坊(系投稿) 3D视觉精品文章汇总:https://github.com/qxiaofan/awesome-3D-Vision-Papers/ 一、前言 请阅读本文之前最好把ORB-SLAM3的单目初始化过程再过一遍(ORB-SLAM3 细读单目初始化过程(上)、超详细解读ORB-SLAM3单目初始化(下篇)),...