编写高性能的.NET代码 - (EPUB全文下载)
文件大小:0.3 mb。
文件格式:epub 格式。
书籍内容:
编写高性能的.NET代码
第1章 性能评估及工具
第2章 垃圾回收
第3章 JIT编译
第4章 异步编程
第5章 编码和类设计的一般规则
第6章 使用.NET Framework
第7章 性能计数器
第8章 ETW事件
第9章 Windows Phone
第10章 代码安全性
第11章 建立追求性能的开发团队
附录A 尽快启动对应用程序的性能讨论
附录B 大O表示法
附录C 参考文献
欢迎来到异步社区!
第1章 性能评估及工具
1.1 选择评估内容
在收集性能数据之前,你需要知道评估的内容是什么。听上去这显而易见,但实际上涉及面远比想象的要广泛得多。就拿内存来说,很显然需要评估内存的占用情况,以便减少内存消耗。但要查看哪类内存呢?专用工作集内存(Private Working Set)、提交大小(Commit Size)、页面缓冲池(Paged Pool)、峰值工作集(Peak Working set)、.NET堆内存大小,还是大对象堆内存(Large Object Heap,LOH)?为了保证负载的均衡,是否要查看各个处理器的堆内存?是否还需要关心其他类型的内存?为了跟踪一段时间内的内存占用情况,是否需要知道每小时的平均值和峰值?内存的占用是否和系统负载相关?现在你明白了吧,光是针对内存,就能轻易地列出一大堆指标。而且目前我们还没有涉及私有堆内存(Private Heap),也没有对程序本身进行评估,还不知道都是哪些对象正在消耗内存呢。
请尽可能明确地描述评估内容。
故事
我曾经负责过一个大型的服务程序,当时我把进程专有内存的大小作为关键的性能指标,根据它来决定是否要在启动内存需求很高的大型任务之前重启进程。这导致了大量的“专有内存”被交换出去,对降低系统的内存负载毫无意义,而我们真正的目标就是要降低内存的负载。我们后来修改了评估系统,转而评估工作集内存,这才产生了效果,把内存占用量减少了几个GB(我说过这是一个大型应用)。
一旦确定了需要评估的内容,接下来就是选择每个指标的目标值。在开发阶段初期,这些目标值可能比较易变,甚至不可能知道。其实在初始阶段不需要满足这些目标值,但这能迫使你建立一套评价体系,依据这些值来自动评估你的工作。这些目标值应该是可量化的。我们对程序的较高要求也许就是要“快”,当然这没错。但这不算是一个很好的指标,因为“快”比较主观,没有什么明确的途径来判断是否达标。你必须能把目标定义成某个数字,而且是可测量的数字。
差的目标:用户界面应该响应迅速。
好的目标:任何操作都不会阻塞UI线程超过20 ms。
但只是能被量化还不够,还需要十分精确,正如前面的内存优化案例中所述。
差的目标:内存占用应该小于1 GB。
好的目标:当负载为每秒100个请求时,工作集内存的占用不能超过1 GB。
第二个版本的目标值给定了非常明确的前提条件,你可以明确知道是否满足需求。实际上,这已给出了一个良好的测试用例。
目标值中的另一个决定因素是应用程序的类型。带有用户界面的程序必须不惜一切代价保证UI线程的响应能力,无论执行任何任务时都应如此。而服务器端程序每秒要处理几十、几百,甚至几千个请求。它必须非常高效地完成I/O操作和数据同步,以保证吞吐量和CPU利用率的最大化。因此服务器端程序的设计完全不同于其他程序。如果某个应用程序的基础架构先天不足,对效率问题考虑欠佳,那么再回头去修正就很难了。
在设计系统和规划性能评估方案时,有一条经验也许很有用,那就是设想一下理论上的最佳性能。如果你能去掉其他所有开销,比如垃圾回收、JIT、线程中断,以及其他任何你能想到的开销,然后还能剩下什么资源用来干活呢?对于负载、内存占用、CPU占用、内部同步等资源,你能想到的理论极限是多少?这通常依赖于程序所处的硬件和操作系统。比如,有1台16个处理器、64GB内存的服务器,带有2条10GB的网络,你需要估计一下最大并行处理能力、内存中最多能存放多少数据,以及每秒的网络吞吐量是多少。这能帮助你作出规划,假如1台服务器不够用,那到底需要多少台同档次的机器。所有这些信息都是性能评估目标的绝佳来源。
你大概听说过一个说法:“过早的优化是万恶之源”,这是由Donald Knuth首先提出的。这句话仅适用于代码层面的微观优化。在设计阶段时,你需要理解整体架构和约束条件,不然你就会遗漏一些关键点,这将严重制约程序的运行。你必须在设计阶段就把性能目标预先考虑进去。
在软件设计阶段,就得考虑安全性等很多方面的问题。性能问题也一样,不能事后再议,必须从一开始就提出明确的目标。要想从头开始把一个已有的应用程序重新设计一遍,这是不可能的,这比一开始就考虑周全要付出多得多的代价。
在项目初始阶段的性能分析,与开发完成即将进入测试阶段的分析是不一样的。在初始阶段必须得保证设计的灵活性,确保技术路线在理论上能完成任务,确保在架构上没有大的问题以免除后患。一旦项目进入测试、部署和维护阶段,就得把更多的精力投入微观优化、具体代码方式的分析、减少内存占用等工作。
最后,你还需要了解阿姆达尔定律(Ahmdals’s Law,参见http://www.writinghighperf.net/go/3[PDF]),特别是其应用于顺序执行程序的情况,以便能找到哪部分程序是需要优化的。那些不能明显改善整体性能的微观优化,多半是在浪费时间。为了获得最佳效果,应该优先优化那些效率最低的部分。优化永远不可能面面俱到,得有一个明智的起点。因此,准备好优化目标,再有一套优秀的评估系统,这些都是十分重要的。不然你连从哪儿开始都不知道。
1.2 平均值还是百分位值
在选择评估值时,需要考虑用什么统计值才合适。多数人会优先选用平均值。当然大部分情况下这确实是个重要指标,但还应该考虑一下百分位值。如果对程序的可用性有要求,肯定会用到百分比形式的性能指标。比如,“数据库请求的平均延迟必须少于10 ms,95%以上的数据库请求延迟必须少于100 ms。”
你可能对这个概念不大熟悉,其实它相当简单。 ............
以上为书籍内容预览,如需阅读全文内容请下载EPUB源文件,祝您阅读愉快。
书云 Open E-Library » 编写高性能的.NET代码 - (EPUB全文下载)