Pro .NET Performance(即 .NET 性能优化)一书的翻译一波三折,从开始到现在 2018 年已经历经多年了。为了不让项目搁浅,我也从 2017 年初开始,开始参与到 Pro .NET Performance 的翻译过程中。终于翻译团队在 2017 年底基本完成了整书的翻译。在这样的背景下,我应约为本书写下这样一篇译者序。期待本书能够尽快出版。
下面是序的全文,请阅读。
在这万众创业的时代,相比于业务形态创新和精益开发能力,在云时代,计算资源显得易于获得,这让更多人相信性能优化已不再是应用程序开发中值得追求的目标。一般来说,当业务形态得以验证,接踵而来的需求就是业务范围和系统容量的迅速扩张了。
要提升应用程序的处理能力,往往有两个选择:在架构方法和部署环境上增加扩展,以及从内部优化应用程序内部的性能。从内部优化性能不光需要对业务场景了如指掌,还需要掌握一些性能优化的独门秘籍。而实施横向扩展在短期内就能起到立竿见影的效果,所以很快成为提升系统处理能力的首选。不过,随着业务规模的持续增加,横向扩展带来的成本也在成倍增加。因而更好的做法是,在横向扩展的同时,同时着手从应用程序内部做优化。
相比于更宏观的架构和部署上的优化,准确的细粒度内部优化,其效果被放大到用户感知的维度上很可能展现为性能成倍的显著提升。比如本书第九章介绍的在计算斐波那契数列时运用缓存技术能让算法的时间复杂度指数级降低。从内部优化时,业务专家可以通过一些业务流程上的简化等方法来有效地改善应用程序的性能,例如,在某些情形下省略一些不必要的运算等。这类优化主要取决于业务规则的自身特点,难以统一地归纳出具体的经验;而在业务之外的优化方法,各种应用程序之间却是相通的。这时一部用以指导我们执行业务无关的性能优化的宝典就显得尤为重要了。本书就是这样的案头必备之选。
尽管本书成书于数年之前,我们仍能看到书中所述的大多数经验仍适用于最新的 .NET 框架和运行时。它不光讲述适用于 .NET 平台的性能优化方法,还详细地讲解了性能度量的指标,以及普适性的性能优化的思路和原理。既授人以鱼,又授人以渔,是不可多得的上佳之作。
本书介绍了大量追求极致性能的方法,但这不意味着我们一定要用尽其中介绍的方法去优化我们编写的每一个应用程序。在编写代码过程中,优先选用更高性能的写法通常是有益的(例如,使用 HashSet 替换 List 来存储需要快速查找的集合)。另一方面,过早优化是所有开发人员都容易忽略的陷阱(例如,集合的元素并不多,又大量用于循环时用 HashSet 替换了 List)。几乎所有新的开发人员都听说过“字符串是不可变量,应该尽量使用 StringBuilder”、“反射的性能很糟糕,应该尽量避免使用”之类的经验之谈。单从字面来理解确实都是金玉良言,但作为一种优化手段,性能优化往往会要求应用程序遵守一些约束,这些约束有时会破坏代码的可读性,有时会改变编写代码的习惯,而后者往往意味着在更广的维度上给团队带来成本。
因而,没必要因为本书的技巧而去对目前的应用程序吹毛求疵地提出要求。相反,有必要掌握一个合适的平衡。在开发功能时,应该将功能的完成度作为第一要素;在重构代码时,应该将简单设计作为首要目标;只有收集了证据表明应用程序的性能需要改善时,才应该安排计划着手优化。
.NET 是一个优秀的现代化开发平台,很多企业在开发现代化商业应用程序时把 .NET 作为首选,特别是新近发布的开源、跨平台的新一代 .NET Core 更是受到广泛关注。与此同时,作为一个托管编程平台,.NET 的性能一直在各种场合为极致性能追求者所质疑,其主要依据是编程平台的性能很大程度上取决于运行时本身的能力,而托管编程平台的性能始终受制于托管运行时本身的性能,因此开发者无法做最彻底的优化。这样的说法不无道理。在比较人与人的时候,有句话说“按大多数人的努力程度之低,还远不到比天赋的时候”。其实它也同样适用于运行时性能的考量。我相信,在优化性能时,绝大多数开发者并不会比运行时的开发者更专业。
本书大量章节都涉及到 .NET 的运行时在性能方面的优化,以及提供给开发者的丰富的调优工具和选项,本书的技能让我们相信,托管运行时平台如果其本身的性能好、能按需定制,我们只要掌握一些技巧,仍然能够基于托管的编程平台构建高性能的应用程序。