改进托管代码的性能


1.如何引导托管代码的性能Review.
可以使用FxCorp.exe分析工具对程序集做静态分析,以确保程序代码满足.net框架的设计指南. 可以通过代码的Review(垃圾回收,线程,异步处理,资源)来评估程序的性能.同时还要识别和避免通用的性能误解.
可以通过CLR Profiler工具来查看托管堆的内部结构,以分析是否保护了过多的垃圾回收活动或内存泄漏.
 
2.如何设计高效的类型
你定义的类是线程安全的吗?当我们使用using属性的时候存在哪些性能问题?当支持类继承的时候存在哪些性能暗示?这些问题都是在类设计的时候要重点考虑的.
 
3.如果高效的管理内存
编写代码以帮助垃圾回收器能够高效的执行它们的工作.最小化隐藏内存分配,避免使用短生命期对象,预先分配内存,将可用内存组成块,强制垃圾收集.你可以通过CLR Profiler工具来识别和分析应用程序的内存分配.
 
4.如何在应用程序中使用多线程
最小化线程创建,使用自我调节的线程池来进行多线程工作.避免为每一次的请求创建线程.同时还要避免使用Thread.Abort和Thread.Suspend.确保对于Asp.net和Web Service的应用程序你已经适当的调节和优化了线程池.

5.如何使用异步调用
为了实现对用户的快速响应.异步调用可能在客户端的应用程序中有用.异步调用也可能在服务器端,峨边是关于I/O限制的操作.实际上对于那些不能增加并行处理能力,或者在初始化异步调用后立即阻塞了调用线程的异步调用,我们都应该尽量避免.在这些场景下,使用异步调用是没有多少益处的.
 
6.如何清理资源
你应该在使用完资源后尽可能快的释放.使用finally块或使用using声明以保证资源在遇到异常时候也能够正常释放.对于实现了IDisposable接口的对象,要确保你调用了对象中的Dispose方法.
 
7.如何避免不必要的装箱操作(boxing)
过多的装箱操作将导致更多的垃圾回收活动和性能问题.因此应该尽量避免将值类型作为引用类型的方式来使用.可考虑使用Array或自定义的集合类来存储值类型.为了识别装箱,可以检查IL中间文件并寻找box和unbox关键字.
 
8.如何处理异常
异常处理可能是有昂贵代价的.对于常规的应用程序逻辑你应该不使用异常处理.实际上,使用结构化的异常处理可以增加代码的健壮性,因此在可能情况还是要使用异常而不是错误的代码.

编写代码要尽量避免不必要的异常处理,避免对在多层结构的各层都对异常进行捕捉而不做处理的重复抛出.必须要使用finally快以保证在出现异常时候资源能够完全回收.在使用finally块的时候并不一定要使用catch块,不跟异常相关的finally块的异常代码是很小的.
 
9.如何高效的使用strings
过多的字符串处理和串联操作导致不必要的内存分配和垃圾回收.当你需要创建一个复杂的字符串处理操作或需要执行多次字符串的连接时候应该使用StringBuilder来完成.
 
10.如何在数组和集合的使用上做出选择.
数组是最块的集合类型,因此当你不需要使用容量动态扩展,搜索或排序等特征时候,应该尽可能使用数组来处理集合.如何需要一个集合类型,选择的时候应该基于功能需求并避免性能陷阱.
>使用ArrayList来存储自定义对象,特别是存在频繁的增删操作时候.避免使用ArrayList来存储字符串.
>使用StringCollection来存储字符串
>使用HashTable来存储不经常改变的大批量数据,或者哪些要频繁根据关键字查询的数据.
>使用ListDictionary来存储小数据量的集合(一般小于10条)
>使用HybridDictionary来存储频繁查询数据,既有ListDictionary的性能优势,又可以在偶尔需要时候扩展容量.
>需要先进先出时候使用队列,当需要先进后出访问数据时候使用堆栈.
>通过索引或关键字快速获取对象应该使用SortedList,对于存在大量数据变化创建不适合.
 
改进数据访问的性能

1.如何改进数据访问性能
你的目标是最小化在客户端和服务器上的处理过程,以及最小化数据在网络上的传输.使用数据库连接池以在多个请求间分享连接.保证你的事务处理尽可能的短以减小锁定的时间并改善并发.但实际上又不应该为了使事务尽可能的短,而多次往返的访问数据库.
 
2.如果分页记录
当选择一种分页方案的时候必须要考服务器端处理,数据量,网络带宽限制和客户端的处理.对于DataAdapter和DataGrid内带的数据分页技术仅仅适合域小数据量的数据集.对于大数据量的数据处理,可以使用Sql的Top关键字或则使用对规则自增长字段的范围限制查询来获取相关记录.通过较复杂的查询还可以使用临时表或缓存来改善性能.
 
3.如何高效的序列化DataSets
缺省的DataSet的的序列化效率使较差的.你可以对DataSets的数据进行压缩后再序列化.在DotNet2.0上已经可以很好的实现DataSet的高效序列化.
 
4.如何操纵BLOB字段.
避免存储的大BLOB数据的重复移动,可以考虑在DB中仅存储文件路径,而将具体的文件放置在文件系统中.在网络的带宽又限制的时候,应该考虑对这种大数据进行分块的传输.在sql server中可以使用ReadText和UpdateText功能来读取和写入数据,而对于Oracle则使用OracleLob类.
 
5.如何在动态sql和存储过程间进行选择.
微软使推荐采用存储过程的,在此不再叙述.对于采用存储过程的时候应该注意:
>尽量避免存储过程的重新编译
>使用Parameters集合来帮助阻止sql注入问题
>避免在存储过程中使用动态sql
>避免在存储过程中混合业务逻辑
如果使用动态sql,应该注意的是
>使用参数集合来阻止sql注入问题
>如果有可能尽量批量声明
>要充分考虑应用程序的可维护性.如你需要决定是更新资源文件还是更新已编译的代码容易
 
6.在DataSet和DataReader间如何选择
在不需要缓存数据时候,使用DataReader可以最快的得到前向只读的数据集.当你需要保持灵活性,或者在分布式应用中为了能够缓存数据和及早的关闭连接,一般又选用DataSet.
 
7.在.Net中如何更高效的使用事务
处理事务一般有数据库事务,ADO.net事务和COM+三种事务处理方式.其选择顺序也是优先选择数据库事务,但当我们逻辑层需要执行的多个数据层方法应用在一个事务中的时候,则必须要启用ADO.Net的事务处理.
COM+是最耗性能也是最慢的事务处理方式,因此一般仅仅在分布式数据库中使用.
 
8.如何优化查询
对于查询的优化基本都是数据库sql优化的过程,在此不再叙述.对于sql server数据库,sql解释器一般会默认帮你做很多sql语句的优化,但对于Oracle数据库则需要我们自己去优化和分析.
 
增加Asp.Net应用的性能

1.如何调节Asp.net的线程池(略)

2.如何处理需要较长执行时间的访问

长处理时间调用会阻塞调用线程,而且可能会快速的导致线程不足,同时也会迅速的导致排队和对请求的拒绝.因此在这种情况下一般要通过异步处理机制来进行,这样在服务器端处理过程中客户端可以显示相关的等待图标或进度条,在处理完成后通过回调或事件客户端又可能第一时间获得通知并获得返回的数据.
 
3.如何缓存数据
asp.net可以通过Cache API来缓存数据,也可以通过output caching或局部页面片断缓存.不断采用哪种方式你必须要考虑适当的缓存策略,同时标识那些你想缓存的数据,确定缓存数据的存放位置以及更新频率等问题.为了更好的获取缓存性能,你还必须调节操作系统或应用的内存限制.
 
4.如何处理Session状态的保存
有进程内,进程外和数据库三种方式来保持Session的数据.进程内的方案可以获取最佳的性能,但是组织了整个系统朝web群集的一个扩展.为了支持这种群集扩展往往需要采用进程外存储Session的方式,但当采用out-of-process时候应该注意保存的所有状态数据应该都是可以序列化的.
 
改进Web Service和Remoting的性能

1.如何处理大数据的传输
如果需要传输大数据量的数据,首先应该配置web.config文件中<httpRuntime>节的配置,由于传输需要较长时间你还应该检查timeout设置.
你可以采用以下几种方法来处理大数据传输
>通过字节数组的方式进行传输:最简单方式但是失败后必须重传
>返回URL后通过http方式来download文件
>使用stream流来进行传输
 
2.如何高效的序列化DataSet实例
为了减少schema的传输数据量可以对表或字段使用别名.对于DataSet中不需要的字段应该尽量避免序列化,而应该仅仅序列化那些需要的DataTable.在DotNet2.0中已经可以支持对DataSet的二进制序列化.
 
3.Web Serive和Remoting的性能比较.
对于采用tcp channel和binary fomatter的Remoting应用往往可以获得最好的分布式性能.对于都采用http传输的Web Service和Remoting性能上不会存在太明显的差别.相关的性能比较可以参考msdn上专门的web service和remoting的性能比较文档.
本文为人月神话博客原创文章,转载请务必注明出处。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值