编写高性能的.NET代码
目录
第1章 性能评估及工具 1
1.1 选择评估内容 1
1.2 平均值还是百分位值 3
1.3 评估工具 4
1.3.1 Visual Studio 5
1.3.2 性能计数器 7
1.3.3 ETW事件 13
1.3.4 PerfView 15
1.3.5 CLR Profiler 18
查看完整
第1章 性能评估及工具 1
1.1 选择评估内容 1
1.2 平均值还是百分位值 3
1.3 评估工具 4
1.3.1 Visual Studio 5
1.3.2 性能计数器 7
1.3.3 ETW事件 13
1.3.4 PerfView 15
1.3.5 CLR Profiler 18
查看完整
作者简介
Ben Watson从2008年开始就已经是微软的软件工程师了。他在必应(Bing)平台的研发团队工作时,建立了一套世界一流、基于.NET的高性能服务应用,足以应付几千台电脑发起的大容量、低延迟请求,用户数量高达几百万。他在业余时间喜欢参加地理寻宝游戏、阅读各种书籍、欣赏古典音乐,享受与妻子Leticia、女儿Emma的欢聚时刻。他还是《C# 4.0 How-To》一书的作者,该书已由Sams出版。
译者简介
戴旭,1973年生,浙江萧山人,西安建筑科技大学计算机应用学士,杭州电子科技大学软件工程硕士,高级项目管理师。
Ben Watson从2008年开始就已经是微软的软件工程师了。他在必应(Bing)平台的研发团队工作时,建立了一套世界一流、基于.NET的高性能服务应用,足以应付几千台电脑发起的大容量、低延迟请求,用户数量高达几百万。他在业余时间喜欢参加地理寻宝游戏、阅读各种书籍、欣赏古典音乐,享受与妻子Leticia、女儿Emma的欢聚时刻。他还是《C# 4.0 How-To》一书的作者,该书已由Sams出版。
译者简介
戴旭,1973年生,浙江萧山人,西安建筑科技大学计算机应用学士,杭州电子科技大学软件工程硕士,高级项目管理师。
本书详细介绍了如何编写高性能的.NET程序,在zui大化托管代码性能的同时,还能保证.NET的特性优势。
本书循序渐进地深入.NET的各个部分,特别是底层的公共语言运行时(Common Language Runtime,CLR),了解CLR是如何完成内存管理、代码编译、并发处理等工作的。本书还详细介绍了.NET的架构,探讨了编程方式如何影响程序的整体性能,在全书中,还分享了发生在微软的一些趣闻轶事。本书的内容偏重于服务器程序,但几乎所有内容也同样适用于桌面端和移动端应用程序。
本书条理清楚,言简意赅,适合有一定.NET基础的读者和想要提高代码性能的C#程序员学习参考。
本书循序渐进地深入.NET的各个部分,特别是底层的公共语言运行时(Common Language Runtime,CLR),了解CLR是如何完成内存管理、代码编译、并发处理等工作的。本书还详细介绍了.NET的架构,探讨了编程方式如何影响程序的整体性能,在全书中,还分享了发生在微软的一些趣闻轶事。本书的内容偏重于服务器程序,但几乎所有内容也同样适用于桌面端和移动端应用程序。
本书条理清楚,言简意赅,适合有一定.NET基础的读者和想要提高代码性能的C#程序员学习参考。
目录
第1章 性能评估及工具 1
1.1 选择评估内容 1
1.2 平均值还是百分位值 3
1.3 评估工具 4
1.3.1 Visual Studio 5
1.3.2 性能计数器 7
1.3.3 ETW事件 13
1.3.4 PerfView 15
1.3.5 CLR Profiler 18
1.3.6 Windbg 20
1.3.7 .NET IL分析器 24
1.3.8 MeasureIt 25
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 使用Task 86
4.2 并行循环 89
4.3 避免阻塞 92
4.4 在非阻塞式I/O中使用Task 92
4.4.1 适应Task的异步编程模式 94
4.4.2 使用高效I/O 96
4.5 async和await 97
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 必要时使用volatile 106
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/Invoke 134
5.9 委托 136
5.10 异常 137
5.11 dynamic 138
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 Framework 151
6.1 全面了解所用API 151
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和ToUpper 158
6.4.3 字符串拼接 158
6.4.4 字符串格式化 158
6.4.5 ToString 159
6.4.6 避免字符串解析 159
6.5 应避免使用正常情况下也会抛出
“异常”的API 159
6.6 避免使用会在LOH分配内存的
API 159
6.7 使用延迟初始化 160
6.8 枚举的惊人开销 161
6.9 对时间的跟踪记录 162
6.10 正则表达式 164
6.11 LINQ 164
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 Averages 172
7.2.2 Instantaneous 173
7.2.3 Deltas 173
7.2.4 Percentages 173
7.3 小结 174
第8章 ETW事件 175
8.1 定义事件 175
8.2 在PerfView中使用自定义
事件 178
8.3 创建自定义ETW事件
Listener 179
8.4 获取EventSource的详细
信息 184
8.5 自定义PerfView分析插件 186
8.6 小结 189
第9章 Windows Phone 190
9.1 评估工具 190
9.2 垃圾回收和内存 191
9.3 JIT 191
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
分析JIT 207
分析异步执行性能 207
附录B 大O表示法 209
常见算法及其复杂度 211
排序算法 211
图论算法 211
查找算法 212
特殊案例 212
附录C 参考文献 213
参考书籍 213
相关人士及博客 213
^ 收 起
第1章 性能评估及工具 1
1.1 选择评估内容 1
1.2 平均值还是百分位值 3
1.3 评估工具 4
1.3.1 Visual Studio 5
1.3.2 性能计数器 7
1.3.3 ETW事件 13
1.3.4 PerfView 15
1.3.5 CLR Profiler 18
1.3.6 Windbg 20
1.3.7 .NET IL分析器 24
1.3.8 MeasureIt 25
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 使用Task 86
4.2 并行循环 89
4.3 避免阻塞 92
4.4 在非阻塞式I/O中使用Task 92
4.4.1 适应Task的异步编程模式 94
4.4.2 使用高效I/O 96
4.5 async和await 97
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 必要时使用volatile 106
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/Invoke 134
5.9 委托 136
5.10 异常 137
5.11 dynamic 138
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 Framework 151
6.1 全面了解所用API 151
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和ToUpper 158
6.4.3 字符串拼接 158
6.4.4 字符串格式化 158
6.4.5 ToString 159
6.4.6 避免字符串解析 159
6.5 应避免使用正常情况下也会抛出
“异常”的API 159
6.6 避免使用会在LOH分配内存的
API 159
6.7 使用延迟初始化 160
6.8 枚举的惊人开销 161
6.9 对时间的跟踪记录 162
6.10 正则表达式 164
6.11 LINQ 164
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 Averages 172
7.2.2 Instantaneous 173
7.2.3 Deltas 173
7.2.4 Percentages 173
7.3 小结 174
第8章 ETW事件 175
8.1 定义事件 175
8.2 在PerfView中使用自定义
事件 178
8.3 创建自定义ETW事件
Listener 179
8.4 获取EventSource的详细
信息 184
8.5 自定义PerfView分析插件 186
8.6 小结 189
第9章 Windows Phone 190
9.1 评估工具 190
9.2 垃圾回收和内存 191
9.3 JIT 191
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
分析JIT 207
分析异步执行性能 207
附录B 大O表示法 209
常见算法及其复杂度 211
排序算法 211
图论算法 211
查找算法 212
特殊案例 212
附录C 参考文献 213
参考书籍 213
相关人士及博客 213
^ 收 起
作者简介
Ben Watson从2008年开始就已经是微软的软件工程师了。他在必应(Bing)平台的研发团队工作时,建立了一套世界一流、基于.NET的高性能服务应用,足以应付几千台电脑发起的大容量、低延迟请求,用户数量高达几百万。他在业余时间喜欢参加地理寻宝游戏、阅读各种书籍、欣赏古典音乐,享受与妻子Leticia、女儿Emma的欢聚时刻。他还是《C# 4.0 How-To》一书的作者,该书已由Sams出版。
译者简介
戴旭,1973年生,浙江萧山人,西安建筑科技大学计算机应用学士,杭州电子科技大学软件工程硕士,高级项目管理师。
Ben Watson从2008年开始就已经是微软的软件工程师了。他在必应(Bing)平台的研发团队工作时,建立了一套世界一流、基于.NET的高性能服务应用,足以应付几千台电脑发起的大容量、低延迟请求,用户数量高达几百万。他在业余时间喜欢参加地理寻宝游戏、阅读各种书籍、欣赏古典音乐,享受与妻子Leticia、女儿Emma的欢聚时刻。他还是《C# 4.0 How-To》一书的作者,该书已由Sams出版。
译者简介
戴旭,1973年生,浙江萧山人,西安建筑科技大学计算机应用学士,杭州电子科技大学软件工程硕士,高级项目管理师。
本书详细介绍了如何编写高性能的.NET程序,在zui大化托管代码性能的同时,还能保证.NET的特性优势。
本书循序渐进地深入.NET的各个部分,特别是底层的公共语言运行时(Common Language Runtime,CLR),了解CLR是如何完成内存管理、代码编译、并发处理等工作的。本书还详细介绍了.NET的架构,探讨了编程方式如何影响程序的整体性能,在全书中,还分享了发生在微软的一些趣闻轶事。本书的内容偏重于服务器程序,但几乎所有内容也同样适用于桌面端和移动端应用程序。
本书条理清楚,言简意赅,适合有一定.NET基础的读者和想要提高代码性能的C#程序员学习参考。
本书循序渐进地深入.NET的各个部分,特别是底层的公共语言运行时(Common Language Runtime,CLR),了解CLR是如何完成内存管理、代码编译、并发处理等工作的。本书还详细介绍了.NET的架构,探讨了编程方式如何影响程序的整体性能,在全书中,还分享了发生在微软的一些趣闻轶事。本书的内容偏重于服务器程序,但几乎所有内容也同样适用于桌面端和移动端应用程序。
本书条理清楚,言简意赅,适合有一定.NET基础的读者和想要提高代码性能的C#程序员学习参考。
比价列表
1人想要
公众号、微信群
缺书网
微信公众号
微信公众号
扫码进群
实时获取购书优惠
实时获取购书优惠