对大型网站,技术涉及面非常广,对硬件,软件,编程语言,Web Service,防火墙等等有很高要求。
面对大量用户,高并发请求,可以使用高性能服务器,高性能编程语言,高性能数据库,加大带宽等,这意味着巨大的投入。
如果你没有这样的打算,而又想获得更好的系统性能,则需要我们精打细算,从"软"的方面着手。
如果你有过以下的一些用法,或者有不同见解,请赐教。
(1)Foreach比for有更好的执行效率。
Foreach所花的时间大约只有for的30%,通过测试结果,在两者都可以使用的情况下,我们推荐效率更高的Foreach。另外用for写入数据的时间大约是读取数据时间的10倍。
(2)避免使用ArrayList
因为任何对象存放到里面,都要转化为System.Object类型,从ArrayList中取出数据要拆箱回原来的类型。建议使用.NET2.0的泛型,这是一个强类型,可以避免装箱拆箱的性能消耗。
(3)不要使用UpperCase,LowerCase转换字符串,再进行比较。用String.Compare代替,他可以忽略大小写进行比较。
(4)用StringBuilder代替字符串连接符"+"
原因,见我的另一篇文章String 和BulidString性能比较和内在机制
(5)避免在循环内声明变量,应该在循环外声明变量,在循环里初始化
1 //避免 2 3 for(int i=0;i<10;i++) 4 5 { 6 7 AnyClass cl=new AnyClass(); 8 9 //…… 10 11 } 12 13 //推荐 14 for(int i=0;i<10;i++) 15 16 { 17 18 cl=new AnyClass(); 19 20 //…… 21 22 }
(6)捕获异常,不用使用System.Exception
1 //避免
2 try
3 {
4 //TODO
5 }
6 catch (Exception ex)
7 {
8 //TODO(虽然简单,但性能较差)
9 }
10
11 //推荐
12 try
13 {
14 //TODO
15 }
16 catch (System.NullReferenceException ex)
17 {
18 //对空对象异常处理
19 }
20 catch (System.ArgumentOutOfRangeException ex)
21 {
22 //超出范围异常处理
23 }
24 catch (System.InvalidCastException ex)
25 {
26 //对异常转化的处理
27 }
(7)不要使用异常控制程序流程。
异常捕获对性能的消耗很大,众所周知的,能避免使用最好不用
1 //避免 2 3 try 4 { 5 result=200/num; 6 } 7 catch (Exception ex) 8 { 9 result=0 10 } 11 12 //推荐 13 try 14 { 15 result=num!=0?200/num:0; 16 } 17 catch (Exception ex) 18 { 19 result=0 20 }
(8)在遇到调用实现IDisposable对象的时候,用Using和try/finally来释放资源
1 //避免
2
3 public void ExceuteCommand()
4 {
5 SqlConnection sql=new SqlConnection(strCon);
6 SqlCommand cmd=new SqlCommand(sql);
7 sql.Dispose();//上面出错,此处有可能永远都调用不到
8 cmd.Dispose();
9 }
10
11 //建议
12
13 //Using内并不是可以放任何对象,只有实现了IDisposable接口的对象才能被使用。
14 //编译器成IL时候,Using会自动把内容放在try/finally里面。
15
16 try
17 {
18 using(SqlConnection sql=new SqlConnection(strCon))
19 {
20 using(SqlCommand cmd=new SqlCommand(sql))
21 {
22 //TODO
23 }
24 }
25 }
26 catch (Exception ex)
27 {
28 //
29 }
30 finally{
31 //或者
32 //sql.Dispose();
33 //cmd.Dispose();
34 }
35
36 //推荐
37
38 因为如果遇到多个实现IDisposable接口的对象需要释放,try/finally更好些
39
40 //推荐
41 SqlConnection sql=null;
42 SqlCommand cmd=null;
43
44 try
45 {
46 sql=new SqlConnection(strCon);
47 cmd=new SqlCommand(sql);
48 sql.Open();
49 cmd.ExecuteNonQuery();
50
51 }
52 finally{
53 if(sql!=null)
54 sql.Dispose();
55 if(cmd!=null)
56 cmd.Dispose();
57 }
(9)避免使用反射,反射是比较浪费性能的操作
通过反射来调用类型或方法,字段或属性是CLR要做更多的工作,如校验参数,检查权限,所以速度是非常慢的。对于打算写一个动态构造类型(晚绑定)的应用程序,可以通过继承,接口,委托来实现。
(10)值类型组合成字符串,请使用.ToStrng()方法,避免装箱操作。
1 //避免 2 3 var str="hello"+1+2; 4 5 //推荐 6 7 var str="hello"+1.ToString()+2.ToString();
(11)StopWatch类测试运行时间
2 class Program
3 {
4 static void Main(string[] args)
5 {
6 Utility.ProcessTimeSpan(Program.Add);
7 Console.Read();
8 }
9
10 public static void Add()
11 {
12 var a = 0;
13 for (int i = 0; i < 100000000; i++)
14 {
15 a++;
16 }
17 }
18 }
19
20 public static class Utility
21 {
22 public static void ProcessTimeSpan(AddHandler addDelegate)
23 {
24 //推荐
25 DateTime start = DateTime.Now;
26 var timer = Stopwatch.StartNew();
27 addDelegate();
28 timer.Stop();
29 Console.WriteLine("Method took {0} ms", timer.ElapsedMilliseconds);
30
31 //传统
32
33 DateTime start = DateTime.Now;
34 SomeCodeToTime();
35 DateTime end = DateTime.Now;
36 Console.WriteLine("Method took {0} ms", (end - start).TotalMilliseconds);
37
38
39
40 }
41 }