ASP.NET编程风格优化C#性能的效果注意事项
2013-04-24 10:31
337 查看
ASP.NET编程风格优化C#性能的效果注意事项:ASP。NET应用研究越来越广泛了,以下仅是我个人的一些编程经验,虽然不是说最好,但是希望对编程爱好者能够养成一个好的编程习惯性,也有点帮助吧。
总结了几个关于编码风格的注意点,来达到优化C#性能的效果。
第一注意点:
在C#编程中,字符型类型是最容易处理出错的地方,字符串是一个相当特别的引用类型,string本省就是一个不可继承的密封类,但是它具有了值类型所应用的特点,但是它在CLR中内存还是保存于托管堆之上。
也就是说,当我们每次定义一个字符串类型的时候,就在堆内存中开辟一端内存,而当我们字符串被修改之后,它会创建一个新的内存。
注意这里的内存是不连续的,而是通过修改栈内地址引用而拼凑字符串,不会改变源字符串在内存中的地址,所以有些开发者总是喜欢使用这样的方法格式化字符串:
1
string ykmaiz.com = select * from +TableName+ where UserName=+Name+;
上述代码,使用了字符串拼凑的方法,因为使用了多重串联,因此会在内存中创建两个不必要的字符串垃圾副本。
其实在C#中,已经为我们提供了StringBuilder和String.Fromat来解决此问题,虽然他们可以实现同样的功能.
但是他们有质的变化,StringBuilder在内存中开辟的是一段连续内存,当增加新字符串时候,它会在栈中指向的同一个堆内存中连续存放字符,这就形成了性能的提升。
所以我们将上面代码改成:
1
string ykmaiz.com=string.Format(select * from {0} where UserName={1},TableName,Name);
第二注意点:
大多数开发者都不知道内置的验证数据类型的方法,如System.Int32,因此很多人都是自己实现的。
其实这是不妥的,因为这些基本类型中都存在自己固有的类型验证方法,下面这个就是自己实现验证的一个字符串是否是数值的代码:
01
public bool CheckIfNumeric(string ykmaiz.com)
02
03
bool IsNumeric=true;
04
05
try
06
{
07
08
int i=Convert.ToInt32(ykmaiz.com);
09
10
}
11
catch(FormatException excepiton)
12
13
{
14
IsNumeric=false;
15
16
}
17
18
return IsNumeric;
虽然使用了try catch语句,这不是最佳的做法,更好的方法是:
1
int output=0;
2
3
bool IsNumeric=int.TryParse(ykmaiz.com,out output);
4
5
//int.TryParse是更快、更简洁的方法
第三注意点:
自己利用IDisposable接口手动释放内存。理想的方法是在使用完对象的时候,在类中实现IDisposable接口中的dispose方法进行内存的释放。
当然在.Net本身提供的垃圾回收机制(GC)中就提供了这样的功能,在我们实例化类对象时,在类本身的析构函数中会调用dispose方法,GC在各级内存堆满的情况下,自动检查对象使用情况,去相应的释放内存。
但是运行在非托管平台上的方法,需要我们自己手动释放内存。
比如我们常见的SqlConnection对象,也就有了下面的创建、使用和处理方法:
01
public void DALOneMethod()
02
03
SqlConnection ykmaizConnection=null;
04
try
05
{
06
ykmaizConnection=new SqlConnection("www.ykmaiz.com");
07
08
//处理代码
09
10
}
11
catch(Exception exception)
12
{
13
// 管理异常
14
}
15
finally
16
{
17
ykmaizConnection.Close();
18
19
ykmaizConnection.Disopse();
20
}
上述代码是大部分开发者会出现的代码,连接处理在最后一个代码中被明确调用。
但是如果发生了一个异常,catch代码块就被执行,然后再执行最后一个代码块处理连接,因此在最后一个代码块执行之前,连接将一直留在内存中,大部分我们会在此处记录错误,一般涉及到IO操作,如果延时时间比较长的话,这个连接将在内存时间长时间停留。
我们一个原则就是当对象不再使用的时候我们里面释放资源。
我们采用程序逻辑域来处理这个问题会更好:
1
using(SqlConnction connection=new SqlConnection(“www.ykmaiz.com”))
2
{
3
// 处理代码
4
}
当使用using代码快时,对象上的dispose()方法将在执行推出逻辑域的时候调用,这样就保证了SqlConnection的资源处理被尽早释。
第四注意点:
学会合理的管理公共变量,我们在系统中经常会滥用公共变量,没有做到合适的封装好。
例如以下代码:
01
static void Main(string[] args)
02
{
03
MyAccount account=new MyAccount();
04
05
//这地方不能随便的调用account里面的字段进行更改,但是缺改了
06
07
account.AccountNumber=“www.ykmaiz.com”;
08
09
Console.ReadKey();
10
}
11
public class MyAccount
12
{
13
public string AccountNumber;
14
15
public MyAcctount()
16
{
17
18
AccountNumber="www.ykmaiz.com/plus/guestbook.php";
19
}
20
}
在上面的MyAccount类中声明了一个AccountNumber公共变量。
理想情况下,AccountNumber应该是只读的,不能让外界修改,但是这里MyAccount类却没有对它做任何控制。
声明公共做法应该是使用属性,如:
01
public class MyAccount
02
{
03
private stirng _accountNumber;
04
05
public string AccountNumber
06
07
get { return _accountNumber; }
08
09
public MyAccount()
10
{
11
12
_accountNumber="www.ykmaiz.com"
13
}
14
}
这里我们封装了AccountNumber公共变量,它变成了只读,不能由调用者类进行修改。
第五注意点:
嵌套的异常处理,有的开发者喜欢在方法末尾加上处理的嵌套方法,例如以下代码:
01
public class YkmaizStudioClass
02
{
03
public void MainMethod()
04
{
05
try
06
{
07
08
//具体操作
09
10
ChildMethod1();
11
}
12
catch (Exception exception)
13
{
14
15
//处理异常
16
}
17
18
private void ChildMethod1()
19
{
20
try
21
{
22
23
//具体操作
24
25
ChildMethod2();
26
}
27
catch (Exception exception)
28
{
29
//处理异常
30
}
31
32
throw;
33
34
}
35
private void ChildMethod2()
36
{
37
try
38
{
39
40
//具体操作
41
}
42
catch (Exception exception)
43
{
44
45
//处理异常
46
}
47
48
throw;
49
}
50
}
如果相同的异常被处理多次,性能开销将会增加。
我们的解决方法是让异常处理方法独立开来,例如以下代码:
01
public class YkmaizStudioClass
02
{
03
public void MainMethod()
04
{
05
try
06
{
07
08
//具体操作
09
10
ChildMethod1();
11
}
12
catch(Exception exception)
13
{
14
15
//处理异常
16
}
17
}
18
19
private void ChildMethod1()
20
{
21
22
//具体操作
23
24
ChildMethod2();
25
}
26
27
private void ChildMethod2()
28
{
29
30
//具体操作
31
32
}
33
}
第六注意点:
大数据量上使用Dataset和DataReader混用。
当单表数据量很大的情况,使用DataSet是一种很不明智的选择,应为DataSet是以DataTable内存形式存放数据量,一次性将数据拖入内存,当数据很大的情况下,这种方式是很吃内存的。
相比DataSer,DataReader就显得优雅很多,它是每次读取一条数据,然后轮询调用机制,但是也有它的弊端,就是相对长连接,但是对内存消耗而言这是有利的。
当然DataSet在大部分应用场景下也是有自己的优点,充分解耦、一次性操作、领域模型操作等方面,两者分情况分场景而用,这里只是稍微提提,根据场景分析区别。
以后也会慢慢分享我的一些有用的经验,希望喜欢的朋友们大家多多关注!
奉贤鲜花/徐汇保洁公司/闵行租车/静安汽车租赁/奉贤婚庆礼仪/颚式破碎机/捆札机/潜水泵/旋塞阀/摆动混合机/螺丝/球磨机/注册公司/装修公司/空调维修/代开发票
总结了几个关于编码风格的注意点,来达到优化C#性能的效果。
第一注意点:
在C#编程中,字符型类型是最容易处理出错的地方,字符串是一个相当特别的引用类型,string本省就是一个不可继承的密封类,但是它具有了值类型所应用的特点,但是它在CLR中内存还是保存于托管堆之上。
也就是说,当我们每次定义一个字符串类型的时候,就在堆内存中开辟一端内存,而当我们字符串被修改之后,它会创建一个新的内存。
注意这里的内存是不连续的,而是通过修改栈内地址引用而拼凑字符串,不会改变源字符串在内存中的地址,所以有些开发者总是喜欢使用这样的方法格式化字符串:
1
string ykmaiz.com = select * from +TableName+ where UserName=+Name+;
上述代码,使用了字符串拼凑的方法,因为使用了多重串联,因此会在内存中创建两个不必要的字符串垃圾副本。
其实在C#中,已经为我们提供了StringBuilder和String.Fromat来解决此问题,虽然他们可以实现同样的功能.
但是他们有质的变化,StringBuilder在内存中开辟的是一段连续内存,当增加新字符串时候,它会在栈中指向的同一个堆内存中连续存放字符,这就形成了性能的提升。
所以我们将上面代码改成:
1
string ykmaiz.com=string.Format(select * from {0} where UserName={1},TableName,Name);
第二注意点:
大多数开发者都不知道内置的验证数据类型的方法,如System.Int32,因此很多人都是自己实现的。
其实这是不妥的,因为这些基本类型中都存在自己固有的类型验证方法,下面这个就是自己实现验证的一个字符串是否是数值的代码:
01
public bool CheckIfNumeric(string ykmaiz.com)
02
03
bool IsNumeric=true;
04
05
try
06
{
07
08
int i=Convert.ToInt32(ykmaiz.com);
09
10
}
11
catch(FormatException excepiton)
12
13
{
14
IsNumeric=false;
15
16
}
17
18
return IsNumeric;
虽然使用了try catch语句,这不是最佳的做法,更好的方法是:
1
int output=0;
2
3
bool IsNumeric=int.TryParse(ykmaiz.com,out output);
4
5
//int.TryParse是更快、更简洁的方法
第三注意点:
自己利用IDisposable接口手动释放内存。理想的方法是在使用完对象的时候,在类中实现IDisposable接口中的dispose方法进行内存的释放。
当然在.Net本身提供的垃圾回收机制(GC)中就提供了这样的功能,在我们实例化类对象时,在类本身的析构函数中会调用dispose方法,GC在各级内存堆满的情况下,自动检查对象使用情况,去相应的释放内存。
但是运行在非托管平台上的方法,需要我们自己手动释放内存。
比如我们常见的SqlConnection对象,也就有了下面的创建、使用和处理方法:
01
public void DALOneMethod()
02
03
SqlConnection ykmaizConnection=null;
04
try
05
{
06
ykmaizConnection=new SqlConnection("www.ykmaiz.com");
07
08
//处理代码
09
10
}
11
catch(Exception exception)
12
{
13
// 管理异常
14
}
15
finally
16
{
17
ykmaizConnection.Close();
18
19
ykmaizConnection.Disopse();
20
}
上述代码是大部分开发者会出现的代码,连接处理在最后一个代码中被明确调用。
但是如果发生了一个异常,catch代码块就被执行,然后再执行最后一个代码块处理连接,因此在最后一个代码块执行之前,连接将一直留在内存中,大部分我们会在此处记录错误,一般涉及到IO操作,如果延时时间比较长的话,这个连接将在内存时间长时间停留。
我们一个原则就是当对象不再使用的时候我们里面释放资源。
我们采用程序逻辑域来处理这个问题会更好:
1
using(SqlConnction connection=new SqlConnection(“www.ykmaiz.com”))
2
{
3
// 处理代码
4
}
当使用using代码快时,对象上的dispose()方法将在执行推出逻辑域的时候调用,这样就保证了SqlConnection的资源处理被尽早释。
第四注意点:
学会合理的管理公共变量,我们在系统中经常会滥用公共变量,没有做到合适的封装好。
例如以下代码:
01
static void Main(string[] args)
02
{
03
MyAccount account=new MyAccount();
04
05
//这地方不能随便的调用account里面的字段进行更改,但是缺改了
06
07
account.AccountNumber=“www.ykmaiz.com”;
08
09
Console.ReadKey();
10
}
11
public class MyAccount
12
{
13
public string AccountNumber;
14
15
public MyAcctount()
16
{
17
18
AccountNumber="www.ykmaiz.com/plus/guestbook.php";
19
}
20
}
在上面的MyAccount类中声明了一个AccountNumber公共变量。
理想情况下,AccountNumber应该是只读的,不能让外界修改,但是这里MyAccount类却没有对它做任何控制。
声明公共做法应该是使用属性,如:
01
public class MyAccount
02
{
03
private stirng _accountNumber;
04
05
public string AccountNumber
06
07
get { return _accountNumber; }
08
09
public MyAccount()
10
{
11
12
_accountNumber="www.ykmaiz.com"
13
}
14
}
这里我们封装了AccountNumber公共变量,它变成了只读,不能由调用者类进行修改。
第五注意点:
嵌套的异常处理,有的开发者喜欢在方法末尾加上处理的嵌套方法,例如以下代码:
01
public class YkmaizStudioClass
02
{
03
public void MainMethod()
04
{
05
try
06
{
07
08
//具体操作
09
10
ChildMethod1();
11
}
12
catch (Exception exception)
13
{
14
15
//处理异常
16
}
17
18
private void ChildMethod1()
19
{
20
try
21
{
22
23
//具体操作
24
25
ChildMethod2();
26
}
27
catch (Exception exception)
28
{
29
//处理异常
30
}
31
32
throw;
33
34
}
35
private void ChildMethod2()
36
{
37
try
38
{
39
40
//具体操作
41
}
42
catch (Exception exception)
43
{
44
45
//处理异常
46
}
47
48
throw;
49
}
50
}
如果相同的异常被处理多次,性能开销将会增加。
我们的解决方法是让异常处理方法独立开来,例如以下代码:
01
public class YkmaizStudioClass
02
{
03
public void MainMethod()
04
{
05
try
06
{
07
08
//具体操作
09
10
ChildMethod1();
11
}
12
catch(Exception exception)
13
{
14
15
//处理异常
16
}
17
}
18
19
private void ChildMethod1()
20
{
21
22
//具体操作
23
24
ChildMethod2();
25
}
26
27
private void ChildMethod2()
28
{
29
30
//具体操作
31
32
}
33
}
第六注意点:
大数据量上使用Dataset和DataReader混用。
当单表数据量很大的情况,使用DataSet是一种很不明智的选择,应为DataSet是以DataTable内存形式存放数据量,一次性将数据拖入内存,当数据很大的情况下,这种方式是很吃内存的。
相比DataSer,DataReader就显得优雅很多,它是每次读取一条数据,然后轮询调用机制,但是也有它的弊端,就是相对长连接,但是对内存消耗而言这是有利的。
当然DataSet在大部分应用场景下也是有自己的优点,充分解耦、一次性操作、领域模型操作等方面,两者分情况分场景而用,这里只是稍微提提,根据场景分析区别。
以后也会慢慢分享我的一些有用的经验,希望喜欢的朋友们大家多多关注!
奉贤鲜花/徐汇保洁公司/闵行租车/静安汽车租赁/奉贤婚庆礼仪/颚式破碎机/捆札机/潜水泵/旋塞阀/摆动混合机/螺丝/球磨机/注册公司/装修公司/空调维修/代开发票
相关文章推荐
- 总结sql数据库性能优化相关的注意事项
- js 性能 优化 提高JS性能注意事项
- SQL 数据库的优化性能注意事项(摘自CSDN论坛)
- 总结出来的一些ASP.NET程序性能优化的注意事项
- JavaScript脚本性能优化注意事项
- js 性能 优化 提高JS性能注意事项
- 数据库性能优化注意事项
- 性能优化注意事项
- mysql性能优化注意事项以及索引
- SQL Server性能优化(5)表设计时的注意事项
- 总结出来的一些ASP.NET程序性能优化的注意事项[不断补充]
- Android性能优化注意事项
- 总结出来的一些ASP.NET程序性能优化的注意事项[不断补充]
- Android 性能优化注意事项
- JavaScript脚本性能优化注意事项
- 性能优化三 使用索引的注意事项
- 总结sql数据库性能优化相关的注意事项
- jQuery性能优化注意事项
- 优化JavaScript脚本的性能的几个注意事项
- Mybatis中SQL性能优化注意事项