C# 代码优化 性能优化【转】
自己所作的項目中開始慢慢接觸到程序的優化部分,慢慢的對這些有了很多的理解。代碼的書寫規范化有助于團隊中成員對你代碼快速的理解。代碼的優化有助于讓程序運行速度更快一些。所以如下特轉一些文字說明和本人的一些愚見。
?
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解決問題很快,不過調試的時候很煩
轉載于:https://www.cnblogs.com/guozhe/archive/2013/05/09/3069043.html
總結
以上是生活随笔為你收集整理的C# 代码优化 性能优化【转】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库多表连接查询
- 下一篇: 通过微软虚拟wifi接入点共享网络连接的