几乎所有的程序员在初学编程之时,都被灌输过“托管语言(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的运行原理有详细的叙述,以下是一些摘要:

C#一定比C++性能差?当然不!破除迷信,从我做起!的更多相关文章

  1. 查询Oracle性能差的、正在执行或执行过的SQL语句

    查找前十条性能差的sql. SELECT * FROM (select PARSING_USER_ID,EXECUTIONS,SORTS, COMMAND_TYPE,DISK_READS,sql_te ...

  2. Rreplication 性能差(转储200万门诊处方zjysb012)

    ETLDB性能差(HIS转储200万门诊处方zjysb012) 解决方法: 1.禁用cdc.Hismz_capture 2.停止cdc.Hismz_capture 3.关闭zjysb012,zjysb ...

  3. 分分钟解决MySQL查询速度慢与性能差

    阅读本文大概需要 6 分钟. 一.什么影响了数据库查询速度 1.1 影响数据库查询速度的四个因素 1.2 风险分析 QPS: QueriesPerSecond意思是“每秒查询率”,是一台服务器每秒能够 ...

  4. 分分钟解决 MySQL 查询速度慢与性能差

    一.什么影响了数据库查询速度 1.1 影响数据库查询速度的四个因素 1.2 风险分析 QPS: QueriesPerSecond意思是“每秒查询率”,是一台服务器每秒能够相应的查询次数,是对一个特定的 ...

  5. EF性能分析(一):动态SQL性能差.从OrderBy开始分析

    1. 问题背景 在我的力推下,部门业务开发转向ABP,其中ORM采用的是EntityFrameworkCore. 然而,在数据查询方面,出现了重大的性能问题... 请看代码: //在一个百万数据量的表 ...

  6. 专业解决 MySQL 查询速度慢与性能差!

    Java技术栈 ,一般把连接数设置得大一些). 并发量:同一时刻数据库服务器处理的请求数量 3.超高的 CPU使用率:CPU资源耗尽出现宕机. 4.磁盘 IO:磁盘 IO性能突然下降.大量消耗磁盘性能 ...

  7. 恕我直言你可能真的不会java第6篇:Stream性能差?不要人云亦云

    一.粉丝的反馈 问:stream比for循环慢5倍,用这个是为了啥? 答:互联网是一个新闻泛滥的时代,三人成虎,以假乱真的事情时候发生.作为一个技术开发者,要自己去动手去做,不要人云亦云. 的确,这位 ...

  8. LIMIT和OFFSET分页性能差!今天来介绍如何高性能分页

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 前言 之前的大多数人分页采用的都是这样: SELEC ...

  9. 凭借对KMP算法的了解,用java实现了一下,结果和java自带的字符串indexOf比,性能差了十倍。。。

    public class KMP { private char[] source = {'a','b','c','b','c','a','b','a','b','d','d','e','f','g', ...

随机推荐

  1. Python计算一个项目中含有的代码行数

    最近想要知道以前做过的project有多少行代码,因为文件太多,直接手工数效率太低,于是编写一个python程序用来计算一个project有多少代码行. 首先,在一个项目中,有很多子文件夹,子文件夹中 ...

  2. php循环生成的表单如何获得其各项值案例

    思路:输入框和按钮是用for循环生成的,不但要获取输入框里的各项值,并且要获取点击按钮的值,要知道是那个按钮被点击了,这里以生成5个为例.如图: 这是提交页面,点击的是“小米”. 这是显示结果,测试显 ...

  3. Java Des加解密方法(c#加密Java解密)

    最近我们用Java把一个用.net编写的老系统重新做了翻版,但是登录还是用.net的登录.这样就会遇到一个比较棘手的问题,我们登录用的cookie信息都是.net用des加密的,但我们不得不用Java ...

  4. 【续】强行在C# Winform中渲染Cocos2d-x 3.6

    [前言] 上一篇讲了怎么把Cocos2d-x 3.6渲染进MFC窗体,这里来讲一下怎么在C# Winform中做到同样的功能.如果你不熟悉MFC的使用但对C# Winform比较在行,请往下看. 这一 ...

  5. 解决mysql 1062 主从错误

    1062错误----主键冲突,出现这种情况就是从库出现插入操作,主库又重新来了一遍,iothread没问题,sqlthread出错 解决方案: 从库操作 mysql> stop slave; Q ...

  6. MySQL管理命令

    1.验证MySQL安装 在成功安装Mysql后,一些基础表会表初始化,在服务器启动后,你可以通过简单的测试来验证Mysql是否工作正常. 使用 mysqladmin 工具来获取服务器状态: 使用 my ...

  7. MongoDB基础之八 备份与恢复

    Mongodb导出与导入 1: 导入/导出可以操作的是本地的mongodb服务器,也可以是远程的.所以,都有如下通用选项:-h host 主机--port port 端口-u username 用户名 ...

  8. MySQL千万级多表关联SQL语句调优

    本文不涉及复杂的底层数据结构,通过explain解释SQL,并根据可能出现的情况,来做具体的优化.   需要优化的查询:使用explain      出现了Using temporary:       ...

  9. spring boot框架eclipse快速搭建

    1.maven安装配置好,使用eclipse创建maven项目(选择maven-archetype-quickstart) 2.然后进入http://docs.spring.io/spring-boo ...

  10. python面向对象编程对象和实例的理解

    给你一个眼神,自己体会