C#一定比C++性能差?当然不!破除迷信,从我做起!

几乎所有的程序员在初学编程之时,都被灌输过“托管语言(Java、C#)性能比非托管语言(C、C++)差好多” 的迷信教条。如果你问他们为什么,他们一定会说:托管语言需要通过虚拟机或JIT编译器对中间语言进行解释,会耗费更多的内存和CPU运算时间,而非托管语言则会被直接编译成本地代码,可以直接运行,省去了大量运算。

那么,事实真的是这个样子吗?当然不是!

持以上论调的程序员一般分两类:一类是用C、C++起家的工程师,他们从来没有用过托管语言,也没有深入了解过相关原理,对托管语言的运行机制有一些误解;还有一类是低级程序员,他们不了解程序编译原理,读不懂也不想读相关的书籍,只是觉得非托管语言很难,会用非托管语言的一定是大神,大神说的肯定是对的。然而,其实很多C、C++工程师想转Java、C# 并不比Java、C#工程师转C、C++容易多少,因为两类语言的编程思想完全不一样,想要转变是非常困难的。

言归正传,为什么我说托管语言的性能不一定比非托管语言低呢?

首先要承认, JIT编译的确会耗费更多的运算时间(相对于本地代码),但这不代表本地代码一定比托管代码性能更好。

中间代码的确是需要JIT编译器在运行时进行解释,翻译成本地代码运行的,这也是很多人产生误解的地方。中间代码的存在是保证程序跨平台运行的核心机制,中间代码可以使得开发人员不再关注自己使用的语言,也不再关注程序运行的目标平台,不论开发者使用VB.NET还是C#,不论程序是要运行在x86平台、x64平台、安腾平台或者ARM平台,不论程序是要运行在Windows XP、Windows 10 还是Linux,开发者都不需要修改自己的代码,真正做到一次编写,多平台运行。虽然C、C++也能实现,但是却有很大的局限性,这个后面会说。

但是,中间代码会造成性能下降吗?会!但是完全可以忽略,甚至在某些时候JIT要比本地代码性能更好。

一方面,微软在JIT编译器中做了多种优化,包括本地代码的缓存机制、分支预测,对于客户端程序,微软还提供了NGen工具,可以将中间代码一次性编译成本地代码;对于服务器程序,在第一次加载程序池时,JIT就已经把所有中间代码解释完成了。所以,如果说性能低,主要表现也就是程序的启动速度会慢一丢丢,运行起来以后就几乎没有影响了。所以说这种影响是可以被忽略的。

但是,就算是客户端应用,微软也建议开发者要做性能测试,然后在判断是否要在生产环境中使用NGen工具优化代码。因为在绝大部分情况下,本地代码的性能甚至要比中间代码还要差!

这里就要简单介绍一下JIT编译器的优势了。对于想C、C++这样的语言,会被编译器直接编译成机器语言,但是由于运行环境不确定,特别是CPU指令的差异。这些差异在编译时都要考虑进去才能保证兼容性。而JIT编译器则可以根据程序所在的平台,使用不同的解释方案,能够最大程度的利用平台的优秀特性,对性能会有很大的提升。

在Jeffery Richter所著的《CLR via C#》中,对JIT的运行原理有详细的叙述,以下是一些摘要:

原文地址:https://www.cnblogs.com/TO-WW/p/6503304.html