Go 我不懂,下面以 C++ 和 C# 对比来说明为什么 C++ 编译慢和 C# 编译快。

C 和 C++ 文件的编译经过几个主要步骤:

  1. 处理续行符处理(“\”)之类的杂事
  2. 词法分析,解析出 tokens 来
  3. 预处理,宏展开,处理 #include ,然后对 #include 包含的文件又重复 1~3 步骤。
  4. 重新词法分析
  5. 语法分析生成抽象语法树 AST
  6. 语义分析
  7. 优化生成代码

C# 的步骤:

  1. 处理续行符处理(“\”)之类的杂事
  2. 词法分析,解析出 tokens 来
  3. 语法分析生成抽象语法树 AST
  4. 语义分析
  5. 优化生成代码

首先,直观的看,从编译阶段上来说 C# 就比 C++ 少,这是一个原因。

另一个原因是语言的编译速度跟语法关系很大,高级语言编译一般是经过词法分析=>语法分析=>语义分析=>优化生成代码几步,如果语言的语法上没有歧义,编译的每个阶段都是独立的,那么编译速度自然就快。

如果不是这样,语法上有歧义,比如 C++ 嵌套模板的">>"和位操作的“>>”,当编译器遇到嵌模板">>"的时候只有先放着,然后往前多看几步才能确定到底是模板的尖括号还是移位,自然比没有语法歧义的语言要慢啦。

再举个例子,C++调用模板函数实例化时可以省略<>让编译器自己去推导最合适的重载,C# 泛型方法调用也可以省略 <>。类似这样的语法元素使得编译器在语法分析阶段就不能够确定一个函数调用是否是函数模板实例化(对于 C# 来说是泛型方法调用)还是一个普通的函数调用,而要等到语义分析阶段才能确定,所以在这一点上 C++ 和 C# 其实都选择牺牲编译速度来为人类减少击键次数做贡献并略微提高了代码的可读性。

还有一个方面是C和C++的编译时代码生成问题产生的:头文件和宏定义会在编译时生成代码,宏展开和引入头文件相当于硬插入了一大段文本,让编译器需要重新从词法分析开始分析,模板什么的虽然不是直接插入文本,但处理起来也很麻烦,消耗了不少的编译时间。如果 C/C++ 不是用头文件而是某种形式的编译模块,多个源文件(编译单元)引用同一个模块那么编译器只需分析一次该模块生成 AST 反复使用,那编译速度也能提升不少。

比起 C/C++ 笨笨的文本插入形式的 #include,C# 编译器完全省去了头文件的编译,你引用的 assembly 直接提供了类型和方法神马的元数据,编译器直接拿来用就好。

最后,因为 C# 没有宏和模板之类的代码生成手段,泛型也是运行时处理的,进一步加快了编译速度。

----------
题外话
关于编译器自举跟编译速度关系不大,目前(VS2013)的 C# 编译器应该是 C++ 写的,编译速度很快,但是 Mono 的编译器是 C# 写的,感觉并不慢,至少没有数量级上的差异。现在连 M$ 新的 C# 编译器 Rosylin 也完全用 C# 写了,还很模块化,性能也不差哦。

说了这么多,其实我的意思是 C++ 和 C# 比 PHP 的编译速度差远了,PHP 是最好的语言!

为什么 C# 比 C++ 编译快那么多的更多相关文章

  1. 让QT编译快一点(增加基础头文件)

    姚冬,中老年程序员 进藤光.杨个毛.欧阳修 等人赞同 我是来反对楼上某些答案的.我曾经用MFC写了金山词霸(大约20多万行),又用Qt写了YY语音(大约100多万行),算是对两种框架都比较有经验.纠正 ...

  2. 为什么golang的开发效率高(编译型的强类型语言、工程角度高、在开发上的高效率主要来自于后发优势,编译快、避免趁编译时间找产品妹妹搭讪,既是强类型语言又有gc,只要通过编译,非业务毛病就很少了)

    作者:阿猫链接:https://www.zhihu.com/question/21098952/answer/21813840来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...

  3. 2020年使用Delphi的25个理由(我觉得四个优点:控件+可视化开发+跨平台+数据库,还有一个编译快,运行快)——人生苦短,我用Delphi!

    25年后从10个使用Delphi的理由到1个至25个使用Delphi 10.3的理由 25年前发布Delphi 1时,我汇总了使用Delphi的十大理由.这是我精通Delphi原始书的序言中的原始列表 ...

  4. iOS: FFMpeg编译和使用问题总结

    iOS: FFmpeg编译和使用问题总结 折磨了我近一周多时间的FFmpeg库编译问题终于解决了,必须得把这一段时间来遇到过的坑全写出来.如果急着解决问题,编译最新版本的FFmpeg库请直接看第二部分 ...

  5. C/C++的编译器|编译环境(非常全面的比较)

    C/C++编译器的一些易混淆概念,总结一下. 关于什么是Unix-like操作系统,常见操作系统间差异,什么是操作系统接口等等,请参考<操作系统宝鉴>. C/C++编译器有哪些? 首先是如 ...

  6. Delphi的核心优势:三快一多

    快是指:开发快(RAD开发),编译快(好像是没有用到LL(1),从而避免了潜在的歧义),运行快(原生代码). 多是指:开发符合PME标准的可视化控件,易开发,易使用,所以第三方控件特别多,这个不用解释 ...

  7. 尝试在CentOS7.2上编译安装Swift

    苹果提供 Ubuntu上构建Swift 的教程,通过这个教程我尝试使用CentOS7.2上玩儿一把.目前已经成功在CentOS7.2上班成功安装 swift 4.0 https://github.co ...

  8. iOS: FFmpeg编译和使用 学习

    ffmpeg是一个多平台多媒体处理工具,处理视频和音频的功能非常强大.目前在网上搜到的iOS上使用FFMPEG的资料都比较陈旧,而FFMPEG更新迭代比较快: 且网上的讲解不够详细,对于初次接触FFM ...

  9. 全图化引擎(AI·OS)中的编译技术

    全图化引擎又称算子执行引擎,它的介绍可以参考从HA3到AI OS -- 全图化引擎破茧之路.本文从算子化的视角介绍了编译技术在全图化引擎中的运用.主要内容有: 1. 通过脚本语言扩展通用算子上的用户订 ...

随机推荐

  1. mybatis 控制台打印sql语句

    其实很简单,打印SQL只需要加一个setting就可以了.亲测可用. mybatis-config.xml: <settings>        <setting name=&quo ...

  2. 日志查看技巧之筛选&去重[排查篇]

    引语:相信大家都会偶尔遇到要排查问题发生的原因的情况,那这种时候,我们最有力后盾就是日志文件了,所以谨记日志记录真的很重要.但是日志文件往往是很大的文件,而且里面有太多的东西可能不是我们需要的,如无数 ...

  3. OpenStack-Ocata版+CentOS7.6 云平台环境搭建 — 1.操作系统环境配置

    1.OpenStack示例的架构介绍 1.1 各节点介绍 (1)控制节点(controller)控制节点(controller)上运行身份服务,镜像服务,计算节点管理,网络管理,各种网络代理和仪表板. ...

  4. postgresql-排序

    postgresql的排序. https://www.cnblogs.com/flying-tiger/p/8120046.html 1.是根据排序数据量的大小来判断,如果数据量少到能够整体放到内存的 ...

  5. Android动态添加Fragment

    Android动态添加Fragment 效果图如下: 项目结构图如下: Fragment1: package com.demo.dongtaifragment; import android.app. ...

  6. 使用.NET Core与Google Optimization Tools实现加工车间任务规划

    前一篇文章<使用.NET Core与Google Optimization Tools实现员工排班计划Scheduling>算是一种针对内容的规划,而针对时间顺序任务规划,加工车间的工活儿 ...

  7. Apache Commons Beanutils 一 (使用PropertyUtils访问Bean属性)

    BeanUtils简要描述 beanutils,顾名思义,是java bean的一个工具类,可以帮助我们方便的读取(get)和设置(set)bean属性值.动态定义和访问bean属性: 细心的话,会发 ...

  8. ACM学习<二>

    穷举算法思想:     一句话:就是从所有可能的情况,搜索出正确的答案. 步骤:     1.对于一种可能的情况,计算其结果.     2.判断结果是否满足,YES计算下一个,no继续步骤1,然后判断 ...

  9. Linux_CentOS-服务器搭建 <四>

    既然tomcat,弄好了,数据库安装好了.我们考虑考虑下.今天带给大家是, 数据库的还原备份: 备份开始:      登录开始: mysql -u root -p  创建一个测试用的数据库test并创 ...

  10. 关于unity3d的ios帧频问题.

    原文:http://blog.csdn.net/spiritring/article/details/17606803 static void Start() { if (Application.pl ...