为了账号安全,请及时绑定邮箱和手机立即绑定

编写高性能的.net代码--前言

标签:
C# 算法
    今天开始阅读《编写高性能的.net代码》,比起国内的类似博客介绍的书,整本书基本1/3都是废话,这本书堪称教科书级别,非常值得阅读,特意进行摘抄,制作脑图分享  

本书的目标 https://github.com/micli/netcoredebugging (代码地址)

图片

图片

图片

图片

●本书的目标 https://github.com/micli/netcoredebugging (代码地址)

●.NET性能问题

●实际上都是由于编程模式不佳,或者是缺少.NET Framework环境的程序优化技能

●NET的快速开发特性会使得人们能够更迅速地编写出臃肿、缓慢、缺乏优化的代码

●导致代码质量低下的原因还有很多:编程水平有限、赶进度、不良设计、缺少人手、偷懒等

●本书目标

●教你如何让托管代码的性能最大化

同时不牺牲或尽量少牺牲.NET的特性优势。你将学到良好的编码技术,知道应该避免哪些做法。

●学习底层的公共语言运行时(Common Language Runtime,CLR)

了解它是如何完成内存管理、代码编译、并发处理等工作的。你将会了解.NET的架构,它既要让程序正常运行,又要安全、可控。你还将知道编程方式将会极大地影响程序的整体性能。

●充分了解.NET架构和高性能编码原则

●如果想获得极佳的性能,你最好要了解垃圾回收器对应用程序的影响

●如果你的目标是高可用性

那你多少都需要关心一下JIT编译过程。如果你用到了泛型系统,那就可能要考虑接口的分发(Dispatch)问题

●NET Framework类库自带的API有没有问题?会不会对性能造成负面影响?

●多种线程同步机制之间是否有优劣之分?

●讨论一些性能评估技术和流程

帮助你和你的团队建立追求性能的习惯。好的性能无法一蹴而就,必须持续改进和关注才能永不退化

●归根结底,你能对程序做出多少性能优化,不仅直接取决于你对自己的代码有多了解,还包括你对底层框架、操作系统、硬件环境的理解程度。这一点对于任何编程平台都是一样的

●为什么选用托管代码

●安全性

●全自动的内存管理

●更高级别的抽象

生产力更高、漏洞更少

●更先进的语言特性

委托、匿名方法和动态类型

●庞大的现成代码库

WCF WPF

●易扩展性

利用反射机制,延迟绑定(Late-bound)的功能模块能轻松地实现动态调用,满足可扩展架构的要求

●强大的调试特性

每个“异常”(Exception)都附带了大量的关联信息。每个对象也都携带了相关元数据,调试器可以详细分析堆内存和堆栈内存,通常都不需要用到调试符号文件(PDB)

●本机代码的使用场景

●有一种情况可以考虑使用本机代码,而不是托管代码

这就是需要使用完整的处理器指令集,特别是某些用到了SIMD(Single Instruction Multiple Data)指令的高级数据处理程序。不过这种情况也在改变

●使用大量已有本机代码库

在这种情况下,你可以考虑在新老代码之间建立接口。如果能把新老代码的关系定义成清晰的API,那就可以让新代码都成为可托管的,与本机代码的交互可以通过简单的接口层来实现。然后你可以逐步把本机代码迁移成托管代码。

●托管代码比本机代码慢吗?

●比较接近真相的说法是:如果你不够严谨,.NET平台能让你轻松写出性能低下的代码。

●JIT:

大部分的代码优化工作就在这一阶段进行。第一次运行时,的确会发生固定的性能损耗,但之后就一直会调用编译后的版本。后面我们将看到,必要时可以针对首次运行损耗采取多种措施来提高性能

●托管应用的稳定性能

●JIT编译器的质量

除少数情况外,即时编译所生成代码的质量一般都是很高的,而且质量还一直在进步,特别是近段时间以来

●Net服务的运行开销

NET提供的服务并非不需要开销,但比你预想的要低。想把这类开销降到零是没有必要的(这也不可能)。只要降到足够低,使得影响程序性能的其他因素变得更为明显就可以了

●内存分配

堆内存的分配不再是问题了,而本机代码应用则不然。垃圾回收过程确实会消耗一些时间,但即便是这点开销也大都能免除,这有赖于应用程序的配置参数

●内存碎片

对于长时间运行的大型本机代码应用而言,内存碎片是个普遍问题。随着时间的推移,碎片问题必定会越来越严重。对于.NET应用程序而言,这不算是个大问题,因为垃圾回收机制会对堆内存进行碎片整理

●经JIT编译的代码

因为代码在执行时要经过JIT编译,所以它们在内存中的位置可以比本机代码更为优化。存在关联的代码常常会被放在一起,很可能就置于同一个内存页中。这样触发缺页中断(Page Fault)的机会就会减少

●在绝大多数场合,“托管代码比本机代码慢吗?”的答案一定是“否”。当然,肯定存在一些场合,托管代码无法逾越运行环境的一些安全约束而影响性能。这种情况远比想象中的要少,而且绝大部分应用程序都无法得到明显改善。

●真的失去控制权了吗

●垃圾回收行为是确定的,通过对内存分配模式、对象作用域、垃圾回收配置参数的调控,你可以明确指定其运行时机。虽然控制的方式与本机代码不同,但控制能力依然存在

●善用而非抵触CLR

●只需善用CLR就能让性能大幅提升。所有框架的设计初衷都希望能被善加利用,.NET也不例外

●CLR的有些优点也是双刃剑。易用的profiling记录、足量的文档、丰富的元数据和ETW事件查看器,这些都有助于快速定位问题

●性能优化的层级

●算法

经验丰富的程序员总是假定是自己的代码有误,而不是去归咎于编译器、平台、操作系统或硬件。这无疑也适用于性能优化工作

●.Net Framework

NET Framework本身绝大部分都是用托管代码实现的,与你自己编写的程序一样

●CLR

CLR。它的组件既有托管代码编写的,又有非托管代码编写的,提供了垃圾回收、类型加载、JIT编译和其他所有.NET特性的支持

●汇编代码

●在做性能优化计划或研究时,应该自上而下地进行。先确保程序结构和算法的合理性,再往下面几层推进。宏观的优化(macro-optimization)总是比微观优化(micro-optimization)更加有效

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消