C# 性能优化细节

1、使用泛型来避免装箱、拆箱操作。

装箱操作会造成GC压力;如果发生在集合中,应该使用泛型集合避免。
对于值类型的集合,使用List<T>来代替ArrayList,使用Dictionary<TKey,TValue>来代替Hashtable。

ArrayList h=new ArrayList();  //不建议
h.Add(1);
List<object> h = new List<object>();  //不建议
h.Add(1);
List<int> h = new List<int>();    //建议
h.Add(1);
2、使用string.Empty给一个空字符串变量赋初始值

String.Empty是一个指代,而””是具体的实现

string filter=“”;//不建议
stringfilter=string.Empty; //建议
3、StringBuilder进行字符串拼接操作

如果要构造一个较长的字符串,尤其是拼接超过10次时(经验值),应使用StringBuilder做字符串拼接操作

//不建议:
string s = null;
for (int i = 0; i < 10000; i++)
{
s += i;
}
//建议:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
{
sb.Append(i);
}
string t = sb.ToString();
4、创建StringBuilder应指定初始大小
默认的初始大小为16,一旦超过即需要Resize一次并增加GC压力。建议根据经验值为其指定初始大小。

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++)
{
sb.Append(i);
}
string s = sb.ToString();
//建议修改为
StringBuilder sb = new StringBuilder(256);
for (int i = 0; i < 10; i++)
{
sb.Append(i);
}
string s = sb.ToString();
5、避免滥用StringBuilder(注意,但还没有用过)

类似str1+str2+str3+str4的字符串拼接操作会被编译为String.Concat(str1,str2,str3,str4),效率反而高于StringBuilder。String.Concat会一次性确定字符串长度,StringBuilder需要做Resize,适用于多次生成string对象的情况。

通过直接设置.Length=0来初始化StringBuilder。

根据实验结果,多次使用同一StringBuilder对象时,通过直接设置.Length=0来初始化速度最快。

StringBuiler sb = new StringBuilder(256);
......
sb.Remove(0, sb.Length); //不建议
sb.Length = 0; //建议
6、复杂值类型变量作为参数时,使用引用方式可提升效率
值类型从调用栈分配,引用类型从托管堆分配。当值类型用作方法参数时,默认会进行参数值复制。

//不建议
static void PrintDateTime(DateTime dt)
{
Console.WriteLine(dt);
}
//建议
static void PrintDateTime(ref DateTime dt)
{
Console.WriteLine(dt);
}
7、使用ItemArray实现对DataRow的批量赋值

在对DataRow的所有字段赋值时,使用字段名进行逐列赋值效率较低。这时应尽量使用批量字段赋值。

可以使用ItemArray或rows.Add方法:

// ds是数据集(DataSet)对象
DataTable dt = ds.Tables[0];
DataRow row = dt.NewRow();
row.ItemArray = new object[] { value1, value2, …, valuen };
// ds是数据集(DataSet)对象
DataTable dt = ds.Tables[0];
dt.Rows.Add(value1, value2, …, valuen);

应避免做大量连续的单列赋值,如下:

DataTable dt = ds.Tables[0];
DataRow row = dt.NewRow();
row["col1"] = value1;
row["col2"] = value2;
…
row["coln"] = valuen;
8、合理使用DataTable的并行计算

DataTable内置的并行计算可以充分利用电脑的每个CPU,起到优化效率的作用。

IEnumerable<DataRow> FindRows() //查找所有数量小于0的分录
{
    DataTable dt = ItemDataTable;
   ……
    return dt.Select(“Quantity<0”); //未使用并行计算
}
IEnumerable<DataRow> FindRows() //查找所有数量小于0的分录
{
    DataTable dt = ItemDataTable;
   ……
    int index = dt.Columns.IndexOf("Quantity");
    return dt.AsEnumerable().AsParallel().Where(dr => (decimal)dr[index] < 0); //使用并行计算:
}

根据实验,当对DataTable的行选择时并行计算优于Select和循环过滤等方式;当进行行遍历时性能类似。

9、使用ImportRow实现向同结构DataTable合并

使用Merge方法可以很方便的实现DataTable的合并,但Merge的效率却非常差代码。示例如下:
DataTable[] srcTables= ... ;
foreach(DataTable src in srcTables)
{
	dest.Merge( src ) ;
}
ImportRow也可以实现DataTable的合并操作,性能相比Merge要高很多。代码示例如下:
DataTable[] srcTables = ... ;
foreach(DataTable src in srcTables )
{
  foreach(DataRow row in src.Rows)
  {
     dest.ImportRow( row ) ;      
  }
}
10、

















  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值