本书详细解释了影响应用程序性能的Windows、CLR和物理硬件的内部结构,并为读者提供了衡量代码如何独立于外部因素执行操作的知识和工具。书中提供了大量的C#代码示例和技巧,将帮助读者zui大限度地提高算法和应用程序的性能,提高个人竞争优势,使用更低的成本获取更多的用户。
本书共11章,D1章和D2章关注性能的度量指标及性能评测;第3章和第4章则深入CLR内部,专注于类型与CLR垃圾回收的内部实现;第5~8章及D11章讨论.NET框架中的几个特定的方面,以及CLR提供的几种可用来进行性能优化的手段;第9章对复杂度理论和算法进行了简单的尝试;D10章则包含了一些独立话题,包括启动时间优化、异常及.NET反射等。
本书适合已经拥有一定C#语言和.NET框架的编程基础,对相关概念较为熟悉的中gao级程序员阅读学习。
本书可以帮助你充分挖掘算法和应用的潜力,避免常见陷阱,优化程序性能,发挥竞争优势,降低运行成本,提高用户满意度。
本书通过介绍大量的分析器和度量工具来指导读者进行性能度量,并讲解了操作系统和CLR是如何以意想不到的方式来影响程序性能的,同时还通过可工作的示例和真实案例来演示性能改进。
通过阅读本书,读者可以学到:
* 找到并定位瓶颈,以获得zui大的性能效果;
* 使用垃圾回收器高效管理内存;
* 更深入地理解底层操作系统及其性能特点,从而更高效地编程;
* 通过并行化、缓存、微优化和许多其他的技术来提升应用程序的性能。
本书包含大量C#代码示例和技巧,可以帮助读者充分利用程序中每一处可能的性能提升,如降低内存占用、一致化CPU使用,减少网络和磁盘的I/O操作等。本书将会改变你对.NET程序开发的思考方式。
Sasha Goldshtein是微软公司Visual C#方向的MVP,也是SELA Group的首席技术官(CTO)。Sasha领导了SELA技术中心的性能与排错团队,并且在多个领域提供咨询服务,包括生产环境调试、应用程序性能排错及分布式架构。Sasha的经验主要集中在C#与C 应用程序开发,以及高可伸缩性和高性能系统架构等方面。他经常在微软公司的相关会议上发表演讲,并举办了如.NET性能.NET调试深入Windows等多项培训课程。
Dima Zurbalev是SELA Group性能与调试团队紧急响应组的高级咨询师。Dima在性能优化和排错上帮助客户完成了许多几乎不可能完成的任务,引导他们深入理解CLR及Windows的内部细节。他的大部分开发经验围绕.NET与C 基础项目进行,同时,他也在为CodePlex上的多个项目贡献代码。
Ido Flatow是微软公司Connected系统方向的MVP,也是SELA团队的高级架构师。他拥有超过15年的行业经验,目前是SELA的Windows Azure及Web领域的专家之一,专长为WCF、ASP.NET、Silverlight及IIS等技术。他是一名微软认证培训师(Microsoft Certified Trainer,MCT),也是微软官方WCF 4.0课程(10263A)的合作者。他同样也经常在微软公司的相关会议上发表演讲。
目 录
第 1章 性能指标1
1.1 性能目标1
1.2 性能指标3
1.3 小结4
第 2章 性能度量5
2.1 性能度量方式5
2.2 Windows内置工具5
2.2.1 性能计数器6
2.2.2 Windows事件追踪10
2.3 时间分析器20
2.3.1 Visual Studio采样分析器20
2.3.2 Visual Studio检测分析器24
2.3.3 时间分析器的gao级用法25
2.4 内存分配分析器27
2.4.1 Visual Studio内存分配
分析器27
2.4.2 CLR分析器29
2.5 内存分析器34
2.5.1 ANTS Memory Profiler34
2.5.2 SciTech .NET Memory
Profiler36
2.6 其他分析器38
2.6.1 数据库和数据访问
分析工具38
2.6.2 并发分析工具38
2.6.3 I/O分析工具40
2.7 微基准测试41
2.7.1 设计不佳的微基准测试
示例41
2.7.2 微基准测试指南44
2.8 小结45
第3章 类型揭秘47
3.1 示例47
3.2 引用类型和值类型在语义上的
区别48
3.3 存储、分配和销毁48
3.4 引用类型揭秘50
3.4.1 方法表51
3.4.2 调用引用类型实例的方法55
3.4.3 非虚方法的分发56
3.4.4 静态方法和接口方法的
分发58
3.4.5 同步块索引和lock
关键字59
3.5 值类型揭秘63
3.6 值类型的虚方法65
3.7 装箱65
3.7.1 避免在调用值类型的Equals
方法时产生装箱67
3.7.2 GetHashCode方法70
3.8 使用值类型的zui佳实践72
3.9 小结72
第4章 垃圾回收73
4.1 为什么需要垃圾回收73
4.1.1 空闲列表管理73
4.1.2 引用计数垃圾回收74
4.2 追踪垃圾回收75
4.2.1 标记阶段76
4.2.2 清理与压缩阶段80
4.2.3 固定82
4.3 垃圾回收器的特征83
4.3.1 垃圾回收时暂停线程83
4.3.2 在垃圾回收时挂起线程83
4.3.3 工作站垃圾回收85
4.3.4 服务器垃圾回收86
4.3.5 切换垃圾回收特征87
4.4 代89
4.4.1 代模型的假设89
4.4.2 .NET中代的实现90
4.4.3 大对象堆93
4.4.4 跨代引用94
4.4.5 后台垃圾回收96
4.5 垃圾回收段和虚拟内存97
4.6 终结化100
4.6.1 手动确定性终结化100
4.6.2 自动的非确定性终结化100
4.6.3 非确定性终结的缺点102
4.6.4 Dispose模式104
4.7 弱引用106
4.8 使用垃圾回收器108
4.8.1 System.GC类108
4.8.2 使用CLR宿主与垃圾
回收器进行交互111
4.8.3 垃圾回收触发器111
4.9 垃圾回收性能zui佳实践112
4.9.1 代模型112
4.9.2 固定113
4.9.3 终结化114
4.9.4 其他建议与zui佳实践114
4.10 小结117
第5章 集合和泛型119
5.1 泛型119
5.1.1 .NET泛型121
5.1.2 泛型约束122
5.1.3 CLR泛型的实现125
5.2 集合131
5.2.1 并发集合132
5.2.2 缓存133
5.3 自定义集合137
5.3.1 分离集(并查集)137
5.3.2 跳跃表138
5.3.3 一次性集合139
5.4 小结141
第6章 并发和并行142
6.1 挑战与所得142
6.2 从线程到线程池,再到任务143
6.2.1 任务并行148
6.2.2 数据并行153
6.2.3 C# 5异步方法156
6.2.4 TPL中的gao级模式159
6.3 同步160
6.3.1 无锁代码161
6.3.2 Windows同步机制165
6.3.3 缓存167
6.4 通用的GPU计算168
6.4.1 C AMP简介169
6.4.2 矩阵相乘171
6.4.3 多体仿真171
6.4.4 tile和共享内存172
6.5 小结175
第7章 网络、I/O和序列化176
7.1 I/O基本概念176
7.1.1 同步与异步I/O176
7.1.2 I/O完成端口177
7.1.3 .NET线程池181
7.1.4 内存复制181
7.2 分散-聚集I/O182
7.3 文件I/O182
7.3.1 缓存提示183
7.3.2 非缓存I/O183
7.4 网络I/O184
7.4.1 网络协议184
7.4.2 网络套接字185
7.5 数据序列化与反序列化186
7.5.1 序列化基准测试187
7.5.2 数据集(DataSet)
序列化189
7.6 Windows通信基础类库189
7.6.1 限流189
7.6.2 处理模型190
7.6.3 缓存191
7.6.4 异步WCF客户端与
服务器191
7.6.5 绑定192
7.7 小结193
第8章 不安全的代码以及互操作194
8.1 不安全的代码194
8.1.1 对象固定与垃圾回收
句柄195
8.1.2 生存期管理196
8.1.3 分配非托管内存196
8.1.4 内存池197
8.2 平台调用198
8.2.1 PInvoke.net与P/Invoke
Interop Assistant软件199
8.2.2 绑定200
8.2.3 列集器存根程序201
8.2.4 原生同构类型204
8.2.5 列集方向、值类型和引用
类型的列集205
8.2.6 代码访问安全性206
8.3 COM互操作性206
8.3.1 生存期管理207
8.3.2 单元列集208
8.3.3 TLB导入与代码访问
安全性209
8.3.4 无主互操作程序集
(NoPIA)209
8.3.5 异常210
8.4 C /CLI语言扩展211
8.4.1 marshal_as辅助库213
8.4.2 IL代码与原生代码214
8.5 Windows 8 WinRT互操作214
8.6 互操作的zui佳实践215
8.7 小结215
第9章 算法优化216
9.1 复杂度的维度216
9.1.1 大O复杂度216
9.1.2 主定理217
9.1.3 图灵机与复杂度分类218
9.1.4 停机问题219
9.1.5 NP完全问题221
9.1.6 记忆与动态规划221
9.1.7 编辑距离222
9.1.8 每对顶点间的zui短路径224
9.2 近似算法226
9.2.1 旅行商问题226
9.2.2 zui大割227
9.3 概率算法227
9.3.1 概率zui大割227
9.3.2 费马质数测试228
9.4 索引与压缩228
9.4.1 变量的长度编码228
9.4.2 压缩索引229
9.5 小结230
第 10章 性能模式232
10.1 JIT编译器优化232
10.1.1 标准的优化方法232
10.1.2 方法内联233
10.1.3 消除边界检查234
10.1.4 尾调用236
10.1.5 启动性能238
10.1.6 使用NGen进行JIT预
编译239
10.1.7 多核后台JIT编译241
10.2 关于启动性能的其他技巧243
10.2.1 将强命名程序集置于
GAC中243
10.2.2 防止本机镜像发生地址
重排243
10.2.3 减少程序集数目244
10.3 处理器相关的优化245
10.3.1 单指令多数据流
(SIMD)245
10.3.2 指令级别并行247
10.4 异常250
10.5 反射250
10.6 代码生成251
10.6.1 直接用源代码生成
代码251
10.6.2 用动态轻量级代码生成技
术(LCG)生成代码253
10.7 小结257
第 11章 Web应用性能258
11.1 测试Web应用的性能258
11.1.1 Visual Studio Web性能
测试和压力测试259
11.1.2 HTTP监控工具260
11.1.3 分析工具260
11.2 提高Web服务器的性能261
11.2.1 缓存公用对象261
11.2.2 使用异步页面、模块和
控制器262
11.2.3 创建异步页面263
11.2.4 创建异步控制器265
11.3 ASP.NET环境调优265
11.3.1 关闭ASP.NET跟踪和调试266
11.3.2 关闭视图状态267
11.3.3 服务端输出缓存268
11.3.4 对ASP.NET应用程序进行预编译269
11.3.5 ASP.NET进程模型调优270
11.4 配置IIS271
11.4.1 输出缓存271
11.4.2 应用程序池配置273
11.5 网络优化274
11.5.1 使用HTTP缓存头274
11.5.2 启用IIS压缩277
11.5.3 精简与合并279
11.5.4 使用内容发布网络 (CDN)280
11.6 对ASP.NET应用程序进行扩容(scaling)281
11.6.1 向外扩容281
11.6.2 ASP.NET扩容机制282
11.6.3 向外扩容的隐患282
11.7 小结283