编辑推荐
想让自己的.NET代码获得zui佳的性能吗?本书将揭开CLR的神秘面纱,不仅教你如何编写性能优异的代码,还能让你“知其所以然”。作者参与设计并搭建的系统是世界上zui大型的高性能.NET系统之一,他在本书中融入了很多的经验教训。本书不仅讲解了CLR的工作机制,还详细介绍了当前获得zui佳性能的新方法,涉及.NET环境下的极致优化、对CLR功能的深入剖析、免费的工具和教程推荐、颇有价值的案例轶事、评测并提升性能的具体步骤。通过阅读本书,你将能够● 选择性能评测指标并知道理由。● 使用众多免费的好工具来快速解决问题。● 理解.NET垃圾回收机制及其对应用程序的影响。● 采用高效的编码模式,以便优化垃圾回收的性能。● 对常见的垃圾回收性能问题做出诊断。● 降低JIT编译的开销。● 让多线程技术得以稳定高效地使用,避免发生同步问题。● 选用.NET特性和API时,能够扬长避短。● 利用代码生成(Code Generation)技术来避免性能问题。● 对性能进行全面测评,发现隐藏较深的性能问题。● 利用性能计数器和ETW事件对程序进行量化分析。● 使用zui新、zui强大的.NET特性。● 确保代码能在移动设备上正确运行。● 建立性能至上的开发团队。
内容简介
本书详细介绍了如何编写高性能的.NET程序,在zui大化托管代码性能的同时,还能保证.NET的特性优势。本书循序渐进地深入.NET的各个部分,特别是底层的公共语言运行时(Common Language Runtime,CLR),了解CLR是如何完成内存管理、代码编译、并发处理等工作的。本书还详细介绍了.NET的架构,探讨了编程方式如何影响程序的整体性能,在全书中,还分享了发生在微软的一些趣闻轶事。本书的内容偏重于服务器程序,但几乎所有内容也同样适用于桌面端和移动端应用程序。 本书条理清楚,言简意赅,适合有一定.NET基础的读者和想要提高代码性能的C#程序员学习参考。
作者简介
作者简介Ben Watson从2008年开始就已经是微软的软件工程师了。他在必应(Bing)平台的研发团队工作时,建立了一套世界一流、基于.NET的高性能服务应用,足以应付几千台电脑发起的大容量、低延迟请求,用户数量高达几百万。他在业余时间喜欢参加地理寻宝游戏、阅读各种书籍、欣赏古典音乐,享受与妻子Leticia、女儿Emma的欢聚时刻。他还是《C# 4.0 How-To》一书的作者,该书已由Sams出版。译者简介戴旭,1973年生,浙江萧山人,西安建筑科技大学计算机应用学士,杭州电子科技大学软件工程硕士,高级项目管理师。
目录
- 第1章 性能评估及工具1
- 1.1 选择评估内容1
- 1.2 平均值还是百分位值3
- 1.3 评估工具4
- 1.3.1 Visual Studio5
- 1.3.2 性能计数器7
- 1.3.3 ETW事件13
- 1.3.4 PerfView15
- 1.3.5 CLR Profiler18
- 1.3.6 Windbg20
- 1.3.7 .NET IL分析器24
- 1.3.8 MeasureIt25
- 1.3.9 代码中的工具25
- 1.3.10 SysInternals工具26
- 1.3.11 数据库26
- 1.3.12 其他工具27
- 1.3.13 评估本身的开销27
- 1.4 小结27
- 第2章 垃圾回收28
- 2.1 基本运作方式30
- 2.2 配置参数33
- 2.2.1 工作站模式还是服务器模式33
- 2.2.2 后台垃圾回收34
- 2.2.3 低延迟模式(Low Latency Mode)35
- 2.3 减少内存分配量36
- 2.4 首要规则37
- 2.5 缩短对象的生存期37
- 2.6 减少对象树的深度38
- 2.7 减少对象间的引用38
- 2.8 避免对象固定38
- 2.9 避免使用终结方法39
- 2.10 避免分配大对象40
- 2.11 避免缓冲区复制41
- 2.12 对长期存活对象和大型对象进行池化41
- 2.13 减少LOH的碎片整理45
- 2.14 某些场合可以强制执行完全回收46
- 2.15 必要时对LOH进行碎片整理47
- 2.16 在垃圾回收之前获得通知47
- 2.17 用弱引用作为缓存50
- 2.18 评估和研究垃圾回收性能51
- 2.18.1 性能计数器51
- 2.18.2 ETW事件52
- 2.18.3 垃圾回收的耗时53
- 2.18.4 内存分配的发生时机54
- 2.18.5 查看已在LOH中分配内存的对象55
- 2.18.6 查看内存堆中的全部对象57
- 2.18.7 为什么对象没有被回收60
- 2.18.8 哪些对象被固定着61
- 2.18.9 内存碎片的产生时机63
- 2.18.10 对象位于第几代内存堆中67
- 2.18.11 第0代内存堆中存活着哪些对象68
- 2.18.12 谁在显式调用GC.Collect方法70
- 2.18.13 进程中存在哪些弱引用70
- 2.19 小结71
- 第3章 JIT编译72
- 3.1 JIT编译的好处73
- 3.2 JIT编译的开销73
- 3.3 JIT编译器优化75
- 3.4 减少JIT编译时间和程序启动时间76
- 3.5 利用Profile优化JIT编译78
- 3.6 使用NGEN的时机78
- 3.6.1 NGEN本机映像的优化79
- 3.6.2 本机代码生成80
- 3.7 JIT无法胜任的场合80
- 3.8 评估81
- 3.8.1 性能计数器81
- 3.8.2 ETW事件82
- 3.8.3 找出JIT耗时最长的方法和模块82
- 3.9 小结83
- 第4章 异步编程84
- 4.1 使用Task86
- 4.2 并行循环89
- 4.3 避免阻塞92
- 4.4 在非阻塞式I/O中使用Task92
- 4.4.1 适应Task的异步编程模式94
- 4.4.2 使用高效I/O96
- 4.5 async和await97
- 4.6 编程结构上的注意事项99
- 4.7 正确使用Timer对象100
- 4.8 合理设置线程池的初始大小101
- 4.9 不要中止线程102
- 4.10 不要改变线程的优先级102
- 4.11 线程同步和锁103
- 4.11.1 真的需要操心性能吗103
- 4.11.2 我真的需要用到同步锁吗104
- 4.11.3 多种同步机制的选择105
- 4.11.4 内存模型106
- 4.11.5 必要时使用volatile106
- 4.11.6 使用Interlocked方法108
- 4.11.7 使用Monitor(锁)110
- 4.11.8 该在什么对象上加锁112
- 4.11.9 异步锁112
- 4.11.10 其他加锁机制115
- 4.11.11 可并发访问的集合类116
- 4.11.12 使用更大范围的锁116
- 4.11.13 替换整个集合117
- 4.11.14 将资源复制给每个线程118
- 4.12 评估118
- 4.12.1 性能计数器118
- 4.12.2 ETW事件119
- 4.12.3 查找争用情况最严重的锁120
- 4.12.4 查找线程在I/O的阻塞位置120
- 4.12.5 利用Visual Studio可视化展示Task和线程121
- 4.13 小结122
- 第5章 编码和类设计的一般规则123
- 5.1 类和“结构”的对比123
- 5.2 重写“结构”的Equals和GetHashCode方法126
- 5.3 虚方法和密封类128
- 5.4 接口的分发(Dispatch)128
- 5.5 避免装箱129
- 5.6 for和foreach的对比131
- 5.7 强制类型转换133
- 5.8 P/Invoke134
- 5.9 委托136
- 5.10 异常137
- 5.11 dynamic138
- 5.12 自行生成代码141
- 5.13 预处理146
- 5.14 评估146
- 5.14.1 ETW事件146
- 5.14.2 查找装箱指令147
- 5.14.3 第一时间发现“异常”149
- 5.15 小结150
- 第6章 使用.NET Framework151
- 6.1 全面了解所用API151
- 6.2 多个API殊途同归152
- 6.3 集合类152
- 6.3.1 泛型集合类153
- 6.3.2 可并发访问的集合类154
- 6.3.3 其他集合类156
- 6.3.4 创建自定义集合类型156
- 6.4 字符串157
- 6.4.1 字符串比较157
- 6.4.2 ToLower和ToUpper158
- 6.4.3 字符串拼接158
- 6.4.4 字符串格式化158
- 6.4.5 ToString159
- 6.4.6 避免字符串解析159
- 6.5 应避免使用正常情况下也会抛出“异常”的API159
- 6.6 避免使用会在LOH分配内存的API159
- 6.7 使用延迟初始化160
- 6.8 枚举的惊人开销161
- 6.9 对时间的跟踪记录162
- 6.10 正则表达式164
- 6.11 LINQ164
- 6.12 读取文件165
- 6.13 优化HTTP参数及网络通讯166
- 6.14 反射167
- 6.15 评估168
- 6.16 性能计数器168
- 6.17 小结169
- 第7章 性能计数器170
- 7.1 使用已有的计数器170
- 7.2 创建自定义计数器171
- 7.2.1 Averages172
- 7.2.2 Instantaneous173
- 7.2.3 Deltas173
- 7.2.4 Percentages173
- 7.3 小结174
- 第8章 ETW事件175
- 8.1 定义事件175
- 8.2 在PerfView中使用自定义事件178
- 8.3 创建自定义ETW事件Listener179
- 8.4 获取EventSource的详细信息184
- 8.5 自定义PerfView分析插件186
- 8.6 小结189
- 第9章 Windows Phone190
- 9.1 评估工具190
- 9.2 垃圾回收和内存191
- 9.3 JIT191
- 9.4 异步编程和内存模式192
- 9.5 其他问题193
- 9.6 小结193
- 第10章 代码安全性194
- 10.1 充分理解底层的操作系统、API和硬件194
- 10.2 把API调用限制在一定范围的代码内194
- 10.3 把性能要求很高、难度很大的代码集中起来并加以抽象199
- 10.4 把非托管代码和不安全代码隔离出来200
- 10.5 除非有证据证明,不然代码清晰度比性能更重要200
- 10.6 小结200
- 第11章 建立追求性能的开发团队201
- 11.1 了解最影响性能的关键区域201
- 11.2 有效的测试201
- 11.3 性能测试平台和自动化202
- 11.4 只认数据203
- 11.5 有效的代码复查203
- 11.6 训练204
- 11.7 小结205
- 附录A 尽快启动对应用程序的性能
- 讨论206
- 定义指标206
- 分析CPU占用情况206
- 分析内存占用情况206
- 分析JIT207
- 分析异步执行性能207
- 附录B 大O表示法209
- 常见算法及其复杂度211
- 排序算法211
- 图论算法211
- 查找算法212
- 特殊案例212
- 附录C 参考文献213
- 参考书籍213
- 相关人士及博客213