編寫高性能的.net代碼--前言
? ? ? ? 今天開始閱讀《編寫高性能的.net代碼》,比起國內(nèi)的類似博客介紹的書,整本書基本1/3都是廢話,這本書堪稱教科書級別,非常值得閱讀,特意進行摘抄,制作腦圖分享

本書的目標 https://github.com/micli/netcoredebugging?(代碼地址)




●本書的目標 https://github.com/micli/netcoredebugging?(代碼地址)
●.NET性能問題
●實際上都是由于編程模式不佳,或者是缺少.NET Framework環(huán)境的程序優(yōu)化技能
●NET的快速開發(fā)特性會使得人們能夠更迅速地編寫出臃腫、緩慢、缺乏優(yōu)化的代碼
●導(dǎo)致代碼質(zhì)量低下的原因還有很多:編程水平有限、趕進度、不良設(shè)計、缺少人手、偷懶等
●本書目標
●教你如何讓托管代碼的性能最大化
同時不犧牲或盡量少犧牲.NET的特性優(yōu)勢。你將學(xué)到良好的編碼技術(shù),知道應(yīng)該避免哪些做法。
●學(xué)習(xí)底層的公共語言運行時(Common Language Runtime,CLR)
了解它是如何完成內(nèi)存管理、代碼編譯、并發(fā)處理等工作的。你將會了解.NET的架構(gòu),它既要讓程序正常運行,又要安全、可控。你還將知道編程方式將會極大地影響程序的整體性能。
●充分了解.NET架構(gòu)和高性能編碼原則
●如果想獲得極佳的性能,你最好要了解垃圾回收器對應(yīng)用程序的影響
●如果你的目標是高可用性
那你多少都需要關(guān)心一下JIT編譯過程。如果你用到了泛型系統(tǒng),那就可能要考慮接口的分發(fā)(Dispatch)問題
●NET Framework類庫自帶的API有沒有問題?會不會對性能造成負面影響?
●多種線程同步機制之間是否有優(yōu)劣之分?
●討論一些性能評估技術(shù)和流程
幫助你和你的團隊建立追求性能的習(xí)慣。好的性能無法一蹴而就,必須持續(xù)改進和關(guān)注才能永不退化
●歸根結(jié)底,你能對程序做出多少性能優(yōu)化,不僅直接取決于你對自己的代碼有多了解,還包括你對底層框架、操作系統(tǒng)、硬件環(huán)境的理解程度。這一點對于任何編程平臺都是一樣的
●為什么選用托管代碼
●安全性
●全自動的內(nèi)存管理
●更高級別的抽象
生產(chǎn)力更高、漏洞更少
●更先進的語言特性
委托、匿名方法和動態(tài)類型
●龐大的現(xiàn)成代碼庫
WCF WPF
●易擴展性
利用反射機制,延遲綁定(Late-bound)的功能模塊能輕松地實現(xiàn)動態(tài)調(diào)用,滿足可擴展架構(gòu)的要求
●強大的調(diào)試特性
每個“異?!保‥xception)都附帶了大量的關(guān)聯(lián)信息。每個對象也都攜帶了相關(guān)元數(shù)據(jù),調(diào)試器可以詳細分析堆內(nèi)存和堆棧內(nèi)存,通常都不需要用到調(diào)試符號文件(PDB)
●本機代碼的使用場景
●有一種情況可以考慮使用本機代碼,而不是托管代碼
這就是需要使用完整的處理器指令集,特別是某些用到了SIMD(Single Instruction Multiple Data)指令的高級數(shù)據(jù)處理程序。不過這種情況也在改變
●使用大量已有本機代碼庫
在這種情況下,你可以考慮在新老代碼之間建立接口。如果能把新老代碼的關(guān)系定義成清晰的API,那就可以讓新代碼都成為可托管的,與本機代碼的交互可以通過簡單的接口層來實現(xiàn)。然后你可以逐步把本機代碼遷移成托管代碼。
●托管代碼比本機代碼慢嗎?
●比較接近真相的說法是:如果你不夠嚴謹,.NET平臺能讓你輕松寫出性能低下的代碼。
●JIT:
大部分的代碼優(yōu)化工作就在這一階段進行。第一次運行時,的確會發(fā)生固定的性能損耗,但之后就一直會調(diào)用編譯后的版本。后面我們將看到,必要時可以針對首次運行損耗采取多種措施來提高性能
●托管應(yīng)用的穩(wěn)定性能
●JIT編譯器的質(zhì)量
除少數(shù)情況外,即時編譯所生成代碼的質(zhì)量一般都是很高的,而且質(zhì)量還一直在進步,特別是近段時間以來
●Net服務(wù)的運行開銷
NET提供的服務(wù)并非不需要開銷,但比你預(yù)想的要低。想把這類開銷降到零是沒有必要的(這也不可能)。只要降到足夠低,使得影響程序性能的其他因素變得更為明顯就可以了
●內(nèi)存分配
堆內(nèi)存的分配不再是問題了,而本機代碼應(yīng)用則不然。垃圾回收過程確實會消耗一些時間,但即便是這點開銷也大都能免除,這有賴于應(yīng)用程序的配置參數(shù)
●內(nèi)存碎片
對于長時間運行的大型本機代碼應(yīng)用而言,內(nèi)存碎片是個普遍問題。隨著時間的推移,碎片問題必定會越來越嚴重。對于.NET應(yīng)用程序而言,這不算是個大問題,因為垃圾回收機制會對堆內(nèi)存進行碎片整理
●經(jīng)JIT編譯的代碼
因為代碼在執(zhí)行時要經(jīng)過JIT編譯,所以它們在內(nèi)存中的位置可以比本機代碼更為優(yōu)化。存在關(guān)聯(lián)的代碼常常會被放在一起,很可能就置于同一個內(nèi)存頁中。這樣觸發(fā)缺頁中斷(Page Fault)的機會就會減少
●在絕大多數(shù)場合,“托管代碼比本機代碼慢嗎?”的答案一定是“否”。當然,肯定存在一些場合,托管代碼無法逾越運行環(huán)境的一些安全約束而影響性能。這種情況遠比想象中的要少,而且絕大部分應(yīng)用程序都無法得到明顯改善。
●真的失去控制權(quán)了嗎
●垃圾回收行為是確定的,通過對內(nèi)存分配模式、對象作用域、垃圾回收配置參數(shù)的調(diào)控,你可以明確指定其運行時機。雖然控制的方式與本機代碼不同,但控制能力依然存在
●善用而非抵觸CLR
●只需善用CLR就能讓性能大幅提升。所有框架的設(shè)計初衷都希望能被善加利用,.NET也不例外
●CLR的有些優(yōu)點也是雙刃劍。易用的profiling記錄、足量的文檔、豐富的元數(shù)據(jù)和ETW事件查看器,這些都有助于快速定位問題
●性能優(yōu)化的層級
●算法
經(jīng)驗豐富的程序員總是假定是自己的代碼有誤,而不是去歸咎于編譯器、平臺、操作系統(tǒng)或硬件。這無疑也適用于性能優(yōu)化工作
●.Net Framework
NET Framework本身絕大部分都是用托管代碼實現(xiàn)的,與你自己編寫的程序一樣
●CLR
CLR。它的組件既有托管代碼編寫的,又有非托管代碼編寫的,提供了垃圾回收、類型加載、JIT編譯和其他所有.NET特性的支持
●匯編代碼
●在做性能優(yōu)化計劃或研究時,應(yīng)該自上而下地進行。先確保程序結(jié)構(gòu)和算法的合理性,再往下面幾層推進。宏觀的優(yōu)化(macro-optimization)總是比微觀優(yōu)化(micro-optimization)更加有效

本文使用 文章同步助手 同步