本書詳細介紹了如何編寫高性能的.NET程序,在zui大化托管代碼性能的同時,還能保證.NET的特性優(yōu)勢。
本書循序漸進地深入.NET的各個部分,特別是底層的公共語言運行時(Common Language Runtime,CLR),了解CLR是如何完成內存管理、代碼編譯、并發(fā)處理等工作的。本書還詳細介紹了.NET的架構,探討了編程方式如何影響程序的整體性能,在全書中,還分享了發(fā)生在微軟的一些趣聞軼事。本書的內容偏重于服務器程序,但幾乎所有內容也同樣適用于桌面端和移動端應用程序。
本書條理清楚,言簡意賅,適合有一定.NET基礎的讀者和想要提高代碼性能的C#程序員學習參考。
想讓自己的.NET代碼獲得zui佳的性能嗎?本書將揭開CLR的神秘面紗,不僅教你如何編寫性能優(yōu)異的代碼,還能讓你知其所以然。作者參與設計并搭建的系統(tǒng)是世界上zui大型的高性能.NET系統(tǒng)之一,他在本書中融入了很多的經(jīng)驗教訓。
本書不僅講解了CLR的工作機制,還詳細介紹了當前獲得zui佳性能的新方法,涉及.NET環(huán)境下的極致優(yōu)化、對CLR功能的深入剖析、免費的工具和教程推薦、頗有價值的案例軼事、評測并提升性能的具體步驟。
通過閱讀本書,你將能夠
● 選擇性能評測指標并知道理由。
● 使用眾多免費的好工具來快速解決問題。
● 理解.NET垃圾回收機制及其對應用程序的影響。
● 采用高效的編碼模式,以便優(yōu)化垃圾回收的性能。
● 對常見的垃圾回收性能問題做出診斷。
● 降低JIT編譯的開銷。
● 讓多線程技術得以穩(wěn)定高效地使用,避免發(fā)生同
步問題。
● 選用.NET特性和API時,能夠揚長避短。
● 利用代碼生成(Code Generation)技術來避
免性能問題。
● 對性能進行全面測評,發(fā)現(xiàn)隱藏較深的性能問題。
● 利用性能計數(shù)器和ETW事件對程序進行量化分析。
● 使用zui新、zui強大的.NET特性。
● 確保代碼能在移動設備上正確運行。
● 建立性能至上的開發(fā)團隊。
作者簡介
Ben Watson從2008年開始就已經(jīng)是微軟的軟件工程師了。他在必應(Bing)平臺的研發(fā)團隊工作時,建立了一套世界一流、基于.NET的高性能服務應用,足以應付幾千臺電腦發(fā)起的大容量、低延遲請求,用戶數(shù)量高達幾百萬。他在業(yè)余時間喜歡參加地理尋寶游戲、閱讀各種書籍、欣賞古典音樂,享受與妻子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 性能計數(shù)器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 數(shù)據(jù)庫26
1.3.12 其他工具27
1.3.13 評估本身的開銷27
1.4 小結27
第2章 垃圾回收28
2.1 基本運作方式30
2.2 配置參數(shù)33
2.2.1 工作站模式還是服務器模式33
2.2.2 后臺垃圾回收34
2.2.3 低延遲模式
(Low Latency Mode)35
2.3 減少內存分配量36
2.4 首要規(guī)則37
2.5 縮短對象的生存期37
2.6 減少對象樹的深度38
2.7 減少對象間的引用38
2.8 避免對象固定38
2.9 避免使用終結方法39
2.10 避免分配大對象40
2.11 避免緩沖區(qū)復制41
2.12 對長期存活對象和大型對象進行
池化41
2.13 減少LOH的碎片整理45
2.14 某些場合可以強制執(zhí)行完全
回收46
2.15 必要時對LOH進行碎片
整理47
2.16 在垃圾回收之前獲得通知47
2.17 用弱引用作為緩存50
2.18 評估和研究垃圾回收性能51
2.18.1 性能計數(shù)器51
2.18.2 ETW事件52
2.18.3 垃圾回收的耗時53
2.18.4 內存分配的發(fā)生時機54
2.18.5 查看已在LOH中分配內存的
對象55
2.18.6 查看內存堆中的全部對象57
2.18.7 為什么對象沒有被回收60
2.18.8 哪些對象被固定著61
2.18.9 內存碎片的產(chǎn)生時機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編譯器優(yōu)化75
3.4 減少JIT編譯時間和程序啟動
時間76
3.5 利用Profile優(yōu)化JIT編譯78
3.6 使用NGEN的時機78
3.6.1 NGEN本機映像的優(yōu)化79
3.6.2 本機代碼生成80
3.7 JIT無法勝任的場合80
3.8 評估81
3.8.1 性能計數(shù)器81
3.8.2 ETW事件82
3.8.3 找出JIT耗時最長的方法和
模塊82
3.9 小結83
第4章 異步編程84
4.1 使用Task86
4.2 并行循環(huán)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 不要改變線程的優(yōu)先級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 可并發(fā)訪問的集合類116
4.11.12 使用更大范圍的鎖116
4.11.13 替換整個集合117
4.11.14 將資源復制給每個線程118
4.12 評估118
4.12.1 性能計數(shù)器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章 編碼和類設計的一般規(guī)則123
5.1 類和結構的對比123
5.2 重寫結構的Equals和
GetHashCode方法126
5.3 虛方法和密封類128
5.4 接口的分發(fā)(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 第一時間發(fā)現(xiàn)異常149
5.15 小結150
第6章 使用.NET Framework151
6.1 全面了解所用API151
6.2 多個API殊途同歸152
6.3 集合類152
6.3.1 泛型集合類153
6.3.2 可并發(fā)訪問的集合類154
6.3.3 其他集合類156
6.3.4 創(chuàng)建自定義集合類型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 優(yōu)化HTTP參數(shù)及網(wǎng)絡
通訊166
6.14 反射167
6.15 評估168
6.16 性能計數(shù)器168
6.17 小結169
第7章 性能計數(shù)器170
7.1 使用已有的計數(shù)器170
7.2 創(chuàng)建自定義計數(shù)器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 創(chuàng)建自定義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 充分理解底層的操作系統(tǒng)、API
和硬件194
10.2 把API調用限制在一定范圍的
代碼內194
10.3 把性能要求很高、難度很大的
代碼集中起來并加以抽象199
10.4 把非托管代碼和不安全代碼
隔離出來200
10.5 除非有證據(jù)證明,不然代碼清晰
度比性能更重要200
10.6 小結200
第11章 建立追求性能的開發(fā)團隊201
11.1 了解最影響性能的關鍵
區(qū)域201
11.2 有效的測試201
11.3 性能測試平臺和自動化202
11.4 只認數(shù)據(jù)203
11.5 有效的代碼復查203
11.6 訓練204
11.7 小結205
附錄A 盡快啟動對應用程序的性能
討論206
定義指標206
分析CPU占用情況206
分析內存占用情況206
分析JIT207
分析異步執(zhí)行性能207
附錄B 大O表示法209
常見算法及其復雜度211
排序算法211
圖論算法211
查找算法212
特殊案例212
附錄C 參考文獻213
參考書籍213
相關人士及博客213