本書詳細(xì)介紹了如何編寫高性能的.NET程序,在zui大化托管代碼性能的同時(shí),還能保證.NET的特性優(yōu)勢(shì)。
本書循序漸進(jìn)地深入.NET的各個(gè)部分,特別是底層的公共語言運(yùn)行時(shí)(Common Language Runtime,CLR),了解CLR是如何完成內(nèi)存管理、代碼編譯、并發(fā)處理等工作的。本書還詳細(xì)介紹了.NET的架構(gòu),探討了編程方式如何影響程序的整體性能,在全書中,還分享了發(fā)生在微軟的一些趣聞?shì)W事。本書的內(nèi)容偏重于服務(wù)器程序,但幾乎所有內(nèi)容也同樣適用于桌面端和移動(dòng)端應(yīng)用程序。
本書條理清楚,言簡意賅,適合有一定.NET基礎(chǔ)的讀者和想要提高代碼性能的C#程序員學(xué)習(xí)參考。
想讓自己的.NET代碼獲得zui佳的性能嗎?本書將揭開CLR的神秘面紗,不僅教你如何編寫性能優(yōu)異的代碼,還能讓你知其所以然。作者參與設(shè)計(jì)并搭建的系統(tǒng)是世界上zui大型的高性能.NET系統(tǒng)之一,他在本書中融入了很多的經(jīng)驗(yàn)教訓(xùn)。
本書不僅講解了CLR的工作機(jī)制,還詳細(xì)介紹了當(dāng)前獲得zui佳性能的新方法,涉及.NET環(huán)境下的極致優(yōu)化、對(duì)CLR功能的深入剖析、免費(fèi)的工具和教程推薦、頗有價(jià)值的案例軼事、評(píng)測(cè)并提升性能的具體步驟。
通過閱讀本書,你將能夠
● 選擇性能評(píng)測(cè)指標(biāo)并知道理由。
● 使用眾多免費(fèi)的好工具來快速解決問題。
● 理解.NET垃圾回收機(jī)制及其對(duì)應(yīng)用程序的影響。
● 采用高效的編碼模式,以便優(yōu)化垃圾回收的性能。
● 對(duì)常見的垃圾回收性能問題做出診斷。
● 降低JIT編譯的開銷。
● 讓多線程技術(shù)得以穩(wěn)定高效地使用,避免發(fā)生同
步問題。
● 選用.NET特性和API時(shí),能夠揚(yáng)長避短。
● 利用代碼生成(Code Generation)技術(shù)來避
免性能問題。
● 對(duì)性能進(jìn)行全面測(cè)評(píng),發(fā)現(xiàn)隱藏較深的性能問題。
● 利用性能計(jì)數(shù)器和ETW事件對(duì)程序進(jìn)行量化分析。
● 使用zui新、zui強(qiáng)大的.NET特性。
● 確保代碼能在移動(dòng)設(shè)備上正確運(yùn)行。
● 建立性能至上的開發(fā)團(tuán)隊(duì)。
作者簡介
Ben Watson從2008年開始就已經(jīng)是微軟的軟件工程師了。他在必應(yīng)(Bing)平臺(tái)的研發(fā)團(tuán)隊(duì)工作時(shí),建立了一套世界一流、基于.NET的高性能服務(wù)應(yīng)用,足以應(yīng)付幾千臺(tái)電腦發(fā)起的大容量、低延遲請(qǐng)求,用戶數(shù)量高達(dá)幾百萬。他在業(yè)余時(shí)間喜歡參加地理尋寶游戲、閱讀各種書籍、欣賞古典音樂,享受與妻子Leticia、女兒Emma的歡聚時(shí)刻。他還是《C# 4.0 How-To》一書的作者,該書已由Sams出版。
譯者簡介
戴旭,1973年生,浙江蕭山人,西安建筑科技大學(xué)計(jì)算機(jī)應(yīng)用學(xué)士,杭州電子科技大學(xué)軟件工程碩士,高級(jí)項(xiàng)目管理師。
目錄
第1章 性能評(píng)估及工具1
1.1 選擇評(píng)估內(nèi)容1
1.2 平均值還是百分位值3
1.3 評(píng)估工具4
1.3.1 Visual Studio5
1.3.2 性能計(jì)數(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 評(píng)估本身的開銷27
1.4 小結(jié)27
第2章 垃圾回收28
2.1 基本運(yùn)作方式30
2.2 配置參數(shù)33
2.2.1 工作站模式還是服務(wù)器模式33
2.2.2 后臺(tái)垃圾回收34
2.2.3 低延遲模式
(Low Latency Mode)35
2.3 減少內(nèi)存分配量36
2.4 首要規(guī)則37
2.5 縮短對(duì)象的生存期37
2.6 減少對(duì)象樹的深度38
2.7 減少對(duì)象間的引用38
2.8 避免對(duì)象固定38
2.9 避免使用終結(jié)方法39
2.10 避免分配大對(duì)象40
2.11 避免緩沖區(qū)復(fù)制41
2.12 對(duì)長期存活對(duì)象和大型對(duì)象進(jìn)行
池化41
2.13 減少LOH的碎片整理45
2.14 某些場合可以強(qiáng)制執(zhí)行完全
回收46
2.15 必要時(shí)對(duì)LOH進(jìn)行碎片
整理47
2.16 在垃圾回收之前獲得通知47
2.17 用弱引用作為緩存50
2.18 評(píng)估和研究垃圾回收性能51
2.18.1 性能計(jì)數(shù)器51
2.18.2 ETW事件52
2.18.3 垃圾回收的耗時(shí)53
2.18.4 內(nèi)存分配的發(fā)生時(shí)機(jī)54
2.18.5 查看已在LOH中分配內(nèi)存的
對(duì)象55
2.18.6 查看內(nèi)存堆中的全部對(duì)象57
2.18.7 為什么對(duì)象沒有被回收60
2.18.8 哪些對(duì)象被固定著61
2.18.9 內(nèi)存碎片的產(chǎn)生時(shí)機(jī)63
2.18.10 對(duì)象位于第幾代內(nèi)存堆中67
2.18.11 第0代內(nèi)存堆中存活著哪些
對(duì)象68
2.18.12 誰在顯式調(diào)用GC.Collect
方法70
2.18.13 進(jìn)程中存在哪些弱引用70
2.19 小結(jié)71
第3章 JIT編譯72
3.1 JIT編譯的好處73
3.2 JIT編譯的開銷73
3.3 JIT編譯器優(yōu)化75
3.4 減少JIT編譯時(shí)間和程序啟動(dòng)
時(shí)間76
3.5 利用Profile優(yōu)化JIT編譯78
3.6 使用NGEN的時(shí)機(jī)78
3.6.1 NGEN本機(jī)映像的優(yōu)化79
3.6.2 本機(jī)代碼生成80
3.7 JIT無法勝任的場合80
3.8 評(píng)估81
3.8.1 性能計(jì)數(shù)器81
3.8.2 ETW事件82
3.8.3 找出JIT耗時(shí)最長的方法和
模塊82
3.9 小結(jié)83
第4章 異步編程84
4.1 使用Task86
4.2 并行循環(huán)89
4.3 避免阻塞92
4.4 在非阻塞式I/O中使用Task92
4.4.1 適應(yīng)Task的異步編程模式94
4.4.2 使用高效I/O96
4.5 async和await97
4.6 編程結(jié)構(gòu)上的注意事項(xiàng)99
4.7 正確使用Timer對(duì)象100
4.8 合理設(shè)置線程池的初始大小101
4.9 不要中止線程102
4.10 不要改變線程的優(yōu)先級(jí)102
4.11 線程同步和鎖103
4.11.1 真的需要操心性能嗎103
4.11.2 我真的需要用到同步鎖嗎104
4.11.3 多種同步機(jī)制的選擇105
4.11.4 內(nèi)存模型106
4.11.5 必要時(shí)使用volatile106
4.11.6 使用Interlocked方法108
4.11.7 使用Monitor(鎖)110
4.11.8 該在什么對(duì)象上加鎖112
4.11.9 異步鎖112
4.11.10 其他加鎖機(jī)制115
4.11.11 可并發(fā)訪問的集合類116
4.11.12 使用更大范圍的鎖116
4.11.13 替換整個(gè)集合117
4.11.14 將資源復(fù)制給每個(gè)線程118
4.12 評(píng)估118
4.12.1 性能計(jì)數(shù)器118
4.12.2 ETW事件119
4.12.3 查找爭用情況最嚴(yán)重的鎖120
4.12.4 查找線程在I/O的阻塞位置120
4.12.5 利用Visual Studio可視化展示
Task和線程121
4.13 小結(jié)122
第5章 編碼和類設(shè)計(jì)的一般規(guī)則123
5.1 類和結(jié)構(gòu)的對(duì)比123
5.2 重寫結(jié)構(gòu)的Equals和
GetHashCode方法126
5.3 虛方法和密封類128
5.4 接口的分發(fā)(Dispatch)128
5.5 避免裝箱129
5.6 for和foreach的對(duì)比131
5.7 強(qiáng)制類型轉(zhuǎn)換133
5.8 P/Invoke134
5.9 委托136
5.10 異常137
5.11 dynamic138
5.12 自行生成代碼141
5.13 預(yù)處理146
5.14 評(píng)估146
5.14.1 ETW事件146
5.14.2 查找裝箱指令147
5.14.3 第一時(shí)間發(fā)現(xiàn)異常149
5.15 小結(jié)150
第6章 使用.NET Framework151
6.1 全面了解所用API151
6.2 多個(gè)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 應(yīng)避免使用正常情況下也會(huì)拋出
異常的API159
6.6 避免使用會(huì)在LOH分配內(nèi)存的
API159
6.7 使用延遲初始化160
6.8 枚舉的驚人開銷161
6.9 對(duì)時(shí)間的跟蹤記錄162
6.10 正則表達(dá)式164
6.11 LINQ164
6.12 讀取文件165
6.13 優(yōu)化HTTP參數(shù)及網(wǎng)絡(luò)
通訊166
6.14 反射167
6.15 評(píng)估168
6.16 性能計(jì)數(shù)器168
6.17 小結(jié)169
第7章 性能計(jì)數(shù)器170
7.1 使用已有的計(jì)數(shù)器170
7.2 創(chuàng)建自定義計(jì)數(shù)器171
7.2.1 Averages172
7.2.2 Instantaneous173
7.2.3 Deltas173
7.2.4 Percentages173
7.3 小結(jié)174
第8章 ETW事件175
8.1 定義事件175
8.2 在PerfView中使用自定義
事件178
8.3 創(chuàng)建自定義ETW事件
Listener179
8.4 獲取EventSource的詳細(xì)
信息184
8.5 自定義PerfView分析插件186
8.6 小結(jié)189
第9章 Windows Phone190
9.1 評(píng)估工具190
9.2 垃圾回收和內(nèi)存191
9.3 JIT191
9.4 異步編程和內(nèi)存模式192
9.5 其他問題193
9.6 小結(jié)193
第10章 代碼安全性194
10.1 充分理解底層的操作系統(tǒng)、API
和硬件194
10.2 把API調(diào)用限制在一定范圍的
代碼內(nèi)194
10.3 把性能要求很高、難度很大的
代碼集中起來并加以抽象199
10.4 把非托管代碼和不安全代碼
隔離出來200
10.5 除非有證據(jù)證明,不然代碼清晰
度比性能更重要200
10.6 小結(jié)200
第11章 建立追求性能的開發(fā)團(tuán)隊(duì)201
11.1 了解最影響性能的關(guān)鍵
區(qū)域201
11.2 有效的測(cè)試201
11.3 性能測(cè)試平臺(tái)和自動(dòng)化202
11.4 只認(rèn)數(shù)據(jù)203
11.5 有效的代碼復(fù)查203
11.6 訓(xùn)練204
11.7 小結(jié)205
附錄A 盡快啟動(dòng)對(duì)應(yīng)用程序的性能
討論206
定義指標(biāo)206
分析CPU占用情況206
分析內(nèi)存占用情況206
分析JIT207
分析異步執(zhí)行性能207
附錄B 大O表示法209
常見算法及其復(fù)雜度211
排序算法211
圖論算法211
查找算法212
特殊案例212
附錄C 參考文獻(xiàn)213
參考書籍213
相關(guān)人士及博客213