C#性能优化:基本代码技巧

这里描述一些应用场景下,可以提高性能的基本代码技巧。对处于关键路径的代码,进行这类的优化还是很有意义的。普通代码可以不做要求,但养成一种好的习惯也是有意义的。

1.7.1 循环写法

可以把循环的判断条件用局部变量记录下来。局部变量往往被编译器优化为直接使用寄存器,相对于普通从堆或栈中分配的变量速度快。如果访问的是复杂计算属性 的话,提升效果将更明显。for (int i = 0, j = collection.GetIndexOf(item); i < j; i++)

需要说明的是:这种写法对于CLR集合类的Count属性没有意义,原因是编译器已经按这种方式做了特别的优化。.

1.7.2 拼装字符串

拼装好之后再删除是很低效的写法。有些方法其循环长度在大部分情况下为1,这种写法的低效就更为明显了:

 public static string ToString(MetadataKey entityKey) { string str = "" ; object [] vals = entityKey.values; for ( int i = 0 ; i < vals.Length; i ++ ) { str += " , " + vals[i].ToString(); } return str == "" ? "" : str.Remove( 0 , 1 );}

推荐下面的写法:

 if (str.Length == 0 )     str = vals[i].ToString(); else     str += " , " + vals[i].ToString();

其实这种写法非常自然,而且效率很高,完全不需要用个Remove方法绕来绕去。

1.7.3 避免两次检索集合元素

获取集合元素时,有时需要检查元素是否存在。通常的做法是先调用ContainsKey(或Contains)方法,然后再获取集合元素。这种写法非常符合逻辑。

但如果考虑效率,可以先直接获取对象,然后判断对象是否为null来确定元素是否存在。对于Hashtable,这可以节省一次GetHashCode调用和n次Equals比较。

如下面的示例:

 public IData GetItemByID(Guid id) { IData data1 = null ; if ( this .idTable.ContainsKey(id.ToString()) { data1 = this .idTable[id.ToString()] as IData; } return data1;}

其实完全可用一行代码完成:return this.idTable[id] as IData;

1.7.4 避免两次类型转换

考虑如下示例,其中包含了两处类型转换:

 if (obj is SomeType) { SomeType st = (SomeType)obj; st.SomeTypeMethod();}

效率更高的做法如下:

 SomeType st = obj as SomeType;  if (st != null )  {  st.SomeTypeMethod();  }