前些日子,爆出N篇说C#/.NET太慢的,要求删除C#/.NET部分特性的文章。
撇开那些文章不说,C#/.NET慢似乎是业界公认的铁则,不论大家如何证明C#/.NET其实不比C++慢多少,但是应用程序级别的性能却依然这么慢。
那么C#/.NET慢在哪里?
很不幸的是大部分c#程序是被大部分程序员拖慢的,也许这个结论不太容易被人接受,却是一个广泛存在的。
String的操作
if(str1.ToUpper()==str2.ToUpper()) |
几乎所有的程序都有String操作,至少90%的程序需要忽略大小写的比较,检查一下代码,至少其中大半的应用程序有类似这样的代码:
或者ToLower版的,甚至我还看到过有个Web的HttpModule里面写上了:
for(inti=0;i<strs.Count;i++) if(value.ToUpper()==strs[i].ToUpper()) //... |
想一下,每个页面请求过来,都要执行这样一段代码,大片大片的创建string实例,更夸张的是还有人说这是用空间换时间。
说这个方法慢,也许还有人不承认,认为这个就是最好的方法,所以这里要用具体测试来摆个事实。
首先准备一个测试性能的方法:
PRivatestaticTResultMeasurePerformance<TArg,TResult>(Func<TArg,TResult>func,TArgarg,intloop) { GC.Collect(); intgc0=GC.CollectionCount(0); intgc1=GC.CollectionCount(1); intgc2=GC.CollectionCount(2); TResultresult=default(TResult); Stopwatchsw=Stopwatch.StartNew(); for(inti=0;i<loop;i++) { result=func(arg); } Console.WriteLine(sw.ElapsedMilliseconds.ToString()+"ms"); Console.WriteLine("GC0:"+(GC.CollectionCount(0)-gc0).ToString()); Console.WriteLine("GC1:"+(GC.CollectionCount(1)-gc1).ToString()); Console.WriteLine("GC2:"+(GC.CollectionCount(2)-gc2).ToString()); returnresult; } |
然后再准备一个堆string:
privatestaticList<string>CreateStrings() { List<string>strs=newList<string>(10000); char[]chs=newchar[3]; for(inti=0;i<10000;i++) { intj=i; for(intk=0;k<chs.Length;k++) { chs[k]=(char)('a'+j%26); j=j/26; } strs.Add(newstring(chs)); } returnstrs; } |