写点什么

有趣的编程语言:Go 语言的启动时间是 C 语言的 300 多倍,C# 的关键字最多

  • 2019-08-28
  • 本文字数:5055 字

    阅读完需:约 17 分钟

有趣的编程语言:Go 语言的启动时间是 C 语言的300多倍,C# 的关键字最多

提到编程语言,大多数的文章内容都这样的:Java 已死?Ruby 的“消亡史”;编程语言排行榜:Go 最流行,Rust 最有前途;Go 语言已经全面碾压 Python…


相信很多读者都已经阅读疲劳了,所以我们这次另辟蹊径,从更有趣的视角来看编程语言,分别是编程语言的启动时间和关键字,帮助开发者更深刻和全面的认识编程语言。

谁的启动时间最少?Go 语言的启动时间是 C 语言的 300 多倍

为什么我们要观察不同编程语言的启动时间呢?因为编程语言的启动时间对于短时间运行的程序非常重要,这些程序由用户交互调用,或者由其他程序(多次)调用。


版本控制系统 Git 是用 C 编写的,调用的命令(如 Git status 和 Git log)执行速度很快。版本控制系统 Bazaar 和 Mercurial 是用 Python 编写的,它们的执行时间比 Git 长得多,并且这种速度的快慢是可被程序员感知到的,导致这种速度差异的主要原因就是 Python 启动时间占据了执行时间的大部分。


为了验证每种编程语言的启动时间各是多少,GitHub 上的一位开发者 bdrung 专门设置了一个小小的项目,项目由许多不同语言的 hello world 程序和一个简单的 Makefile 组成,Makefile 编译程序并运行基准测试,每个程序通过一行代码(使用一个很小的 run.c 程序来最小化调用的开销)运行 1000 次:


time -f “%e” taskset -c 0 ./run 1000 $program


在运行基准测试之前,安装相关的编译器,如果是在 Debian / Ubuntu 上,可以运行 make install 以安装编译器,然后通过调用 make 启动基准。


测试结果如下:


LanguageversionIntel Core i5 2400SRaspberry Pi 3
Pascal (fpc)3.0.2 / 3.0.40.08 ms0.66 ms
C (gcc)7.2.00.26 ms2.19 ms
Shell (dash)0.5.80.33 ms2.81 ms
Go (go)1.8.3 / 1.9.30.41 ms4.10 ms
Rust (rustc)1.21.0 / 1.22.10.51 ms4.42 ms
D (gdc)7.2.00.57 ms
Lua5.2.40.63 ms6.23 ms
Bash4.4.12(1)0.71 ms7.31 ms
C++ (g++)7.2.00.79 ms8.24 ms
Perl5.26.0 / 5.26.10.94 ms8.78 ms
Haskell (ghc)8.0.20.72 ms9.44 ms
ZShell5.2 / 5.4.21.57 ms11.04 ms
CShell201105023.26 ms10.98 ms
Python (with -S)2.7.142.91 ms32.77 ms
Python2.7.149.43 ms91.85 ms
PHP7.1.11 / 7.2.28.71 ms98.03 ms
Cython0.25.2 / 0.26.19.91 ms98.71 ms
Python3 (with -S)3.6.3 / 3.6.49.31 ms110.02 ms
C# (mcs)4.6.2.013.37 ms137.53 ms
PyPy5.8.027.53 ms183.50 ms
Cython30.25.2 / 0.26.126.04 ms196.36 ms
Python33.6.3 / 3.6.425.84 ms197.79 ms
Ruby2.3.3p222 / 2.3.6p38432.43 ms421.53 ms
Java (javac)1.8.0_15154.55 ms566.66 ms
Go (gccgo)7.2.098.26 ms898.30 ms
Scala (scalac)2.11.8310.81 ms2989.72 ms


我们稍稍给这些结果分一下类,分为快速、普通、较慢、很慢。


如果在 Intel Core i5 2400S 的启动时间低于 1 ms,在 Raspberry Pi 3 的启动时间低于 10 ms,我们就认为这类编程语言的启动速度是快速,其中包括 Bash、C、C++、D (gdc)、Go (go)、Haskell、Lua、Pascal、Perl、Rust 和 Shell (dash)。


如果在 Intel Core i5 2400S 的启动时间介于 1 ms 到 5 ms 之间,在 Raspberry Pi 3 的启动时间介于 10 ms 到 50 ms 之间,那么我们就认为这类编程语言的启动速度是普通,其中包括 CShell、Python 2 (with -S)和 ZShell。


如果在 Intel Core i5 2400S 的启动时间介于 5 ms 到 50 ms 之间,在 Raspberry Pi 3 的启动时间介于 50 ms 到 500 ms 之间,那么我们就认为这类编程语言的启动速度是较慢,其中包括 C# (mcs)、Cython (Python 2)、Cython3 (Python 3)、PHP、Python 2、Python 3、Python 3 (with -S)、PyPy (Python 2)和 Ruby。


如果在 Intel Core i5 2400S 的启动时间超过 50ms,在 Raspberry Pi 3 的启动时间超过 500ms,我们就认为这类编程语言启动速度特别慢,其中包括 Java、Go (gccgo)和 Scala。

从关键字的多少来看编程语言的复杂性,C#的关键字最多(77 个)

想要使用编程语言就避不开关键字,编程语言中关键字的数量在一定程度上可以表明编程语言的复杂性,甚至还会影响到开发者利用该编程语言创造的相应程序的复杂性,而复杂的程序维护成本更高,招聘难度也会升级。


编程语言关键字的统计最早是由 @leighmcculloch 开始做的,下图是他的统计结果。



之后,GitHub 上的开发者 e3b0c442 对这个话题也非常感兴趣,所以他也做了一个相似的统计,下面我们就来看一下他的统计结果吧。


编程语言的具体关键字情况如下:


C (ANSI) (32 keywords)


http://port70.net/~nsz/c/c89/c89-draft.html#3.1.1


autobreakcasechar
constcontinuedefaultdo
doubleelseenumextern
floatforgotoif
intlongregisterreturn
shortsignedsizeofstatic
structswitchtypedefunion
unsignedvoidvolatilewhile


C (C18) (44 keywords)


http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf


autobreakcasechar
constcontinuedefaultdo
doubleelseenumextern
floatforgotoif
inlineintlongregister
restrictreturnshortsigned
sizeofstaticstructswitch
typedefunionunsignedvoid
volatilewhile_Alignas_Alignof
_Atomic_Bool_Complex_Generic
_Imaginary_Noreturn_Static_assert_Thread_local


C# (5.0) (77 keywords)


https://download.microsoft.com/download/0/B/D/0BDA894F-2CCD-4C2C-B5A7-4EB1171962E5/CSharp%20Language%20Specification.docx


abstractasbasebool
breakbytecasecatch
charcheckedclassconst
continuedecimaldefaultdelegate
dodoubleelseenum
eventexplicitexternfalse
finallyfixedfloatfor
foreachgotoifimplicit
inintinterfaceinternal
islocklongnamespace
newnullobjectoperator
outoverrideparamsprivate
protectedpublicreadonlyref
returnsbytesealedshort
sizeofstackallocstaticstring
structswitchthisthrow
truetrytypeofuint
ulonguncheckedunsafeushort
usingvirtualvoidvolatile
while


C++ (C++17) (73 keywords)


http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf


alignasalignofasmauto
boolbreakcasecatch
charchar16_tchar32_tclass
constconstexprconst_castcontinue
decltypedefaultdeletedo
doubledynamic_castelseenum
explicitexportexternfalse
floatforfriendgoto
ifinlineintlong
mutablenamespacenewnoexcept
nullptroperatorprivateprotected
publicregisterreinterpret_castreturn
shortsignedsizeofstatic
static_assertstatic_caststructswitch
templatethisthread_localthrow
truetrytypedeftypeid
typenameunionunsignedusing
virtualvoidvolatilewchar_t
while


Dart (1) (33 keywords)


http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-408.pdf


assertbreakcasecatch
classconstcontinuedefault
doelseenumextends
falsefinalfinallyfor
ifinisnew
nullrethrowreturnsuper
switchthisthrowtrue
tryvarvoidwhile
with


Elixir (1.7) (15 keywords)


https://github.com/elixir-lang/elixir/blob/master/lib/elixir/pages/Syntax%20Reference.md


truefalsenilwhen
andornotin
fndoendcatch
rescueafterelse


Erlang (21.2) (27 keywords)


http://erlang.org/doc/reference_manual/introduction.html#reserved-words


afterandandalsoband
beginbnotborbsl
bsrbxorcasecatch
conddivendfun
ifletnotof
ororelsereceiverem
trywhenxor


Go (1.11) (25 keywords)


https://golang.org/ref/spec#Keywords


breakcasechanconst
continuedefaultdeferelse
fallthroughforfuncgo
gotoifimportinterface
mappackagerangereturn
selectstructswitchtype
var


JS (ES2018) (34 keywords)


https://www.ecma-international.org/ecma-262/9.0/index.html#sec-keywords


awaitbreakcasecatch
classconstcontinuedebugger
defaultdeletedoelse
exportextendsfinallyfor
functionifimportin
instanceofnewreturnsuper
switchthisthrowtry
typeofvarvoidwhile
withyield


Java (SE 11) (51 keywords)


https://docs.oracle.com/javase/specs/jls/se11/html/jls-3.html#jls-3.9


abstractassertbooleanbreak
bytecasecatchchar
classconstcontinuedefault
dodoubleelseenum
extendsfinalfinallyfloat
forifgotoimplements
importinstanceofintinterface
longnativenewpackage
privateprotectedpublicreturn
shortstaticstrictfpsuper
switchsynchronizedthisthrow
throwstransienttryvoid
volatilewhile


Kotlin (1.3) (30 keywords)


https://kotlinlang.org/docs/reference/keyword-reference.html


asas?breakclass
continuedoelsefalse
forfunifin
interfaceis
nullobjectpackagereturn
superthisthrowtrue
trytypealiasvalvar
whenwhile


PHP (7.0) (67 keywords)


http://php.net/manual/en/reserved.keywords.php


__halt_compiler()abstractandarray()
asbreakcallablecase
catchclasscloneconst
continuedeclaredefaultdie()
doechoelseelseif
empty()enddeclareendforendforeach
endifendswitchendwhileeval()
exit()extendsfinalfinally
forforeachfunctionglobal
gotoifimplementsinclude
include_onceinstanceofinsteadofinterface
isset()list()namespacenew
orprintprivateprotected
publicrequirerequire_oncereturn
staticswitchthrowtrait
tryunset()usevar
whilexoryield


Python (2.7) (31 keywords)


https://docs.python.org/2/reference/lexical_analysis.html#keywords


andasassertbreak
classcontinuedefdel
elifelseexceptexec
finallyforfromglobal
ifimportinis
lambdanotorpass
printraisereturntry
whilewithyield


Python (3.7) (35 keywords)


https://docs.python.org/3.7/reference/lexical_analysis.html#keywords


FalseNoneTrueand
asassertasyncawait
breakclasscontinuedef
delelifelseexcept
finallyforfromglobal
ifimportinis
lambdanonlocalnotor
passraisereturntry
whilewithyield


R (3.5) (20 keywords)


https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Reserved-words


FALSEInfNA
NA_character_NA_complex_NA_integer_NA_real_
NaNNULLTRUEbreak
elseforfunctionif
innextrepeatwhile


Ruby (2.5) (41 keywords)


https://docs.ruby-lang.org/en/2.5.0/keywords_rdoc.html


ENCODINGLINEFILEBEGIN
ENDaliasandbegin
breakcaseclassdef
defined?doelseelsif
endensurefalsefor
ifinmodulenext
nilnotorredo
rescueretryreturnself
superthentrueundef
unlessuntilwhenwhile
yield


Rust (1.31) (53 keywords)


https://doc.rust-lang.org/grammar.html#keywords


_abstractalignofas
becomeboxbreakconst
continuecratedoelse
enumexternfalsefinal
fnforifimpl
inletloopmacro
matchmodmovemut
offsetofoverrideprivproc
pubpurerefreturn
Selfselfsizeofstatic
structsupertraittrue
typetypeofunsafeunsized
usevirtualwherewhile
yield


Scala (2.12) (40 keywords)


https://scala-lang.org/files/archive/spec/2.12/01-lexical-syntax.html


abstractcasecatchclass
defdoelseextends
falsefinalfinallyfor
forSomeifimplicitimport
lazymacromatchnew
nullobjectoverridepackage
privateprotectedreturnsealed
superthisthrowtrait
trytruetypeval
varwhilewithyield


Swift (4.2) (70 keywords)


https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html


associatedtypeclassdeinitenum
extensionfileprivatefuncimport
initinoutinternallet
openoperatorprivateprotocol
publicstaticstructsubscript
typealiasvarbreakcase
continuedefaultdeferdo
elsefallthroughforguard
ifinrepeatreturn
switchwherewhileas
Anycatchfalseis
nilrethrowssuperself
Selfthrowthrowstrue
try_#available#colorLiteral
#column#else#elseif#endif
#error#file#fileLiteral#function
#if#imageLiteral#line#selector
#sourceLocation#warning


编程语言与关键字个数对比表:


编程语言关键字个数
C(ANSI)32
C(C18)44
C#(5.0)77
C ++(C ++ 17)73
Dart(1)33
Elixir(1.7)15
Erlang(21.2)27
Go(1.11)25
JS(ES2018)34
Java(SE 11)51
Kotlin(1.3)30
PHP(7.0)67
Python(2.7)31
Python(3.7)35
R(3.5)20
Ruby(2.5)41
Rust(1.31)53
Scala(2.12)40
Swift(4.2)70


总体来看,编程语言的关键字都集中在两位数,关键字个数在 50 以上的共有 6 个,其中最多的是 C#,共有 77 个关键字;关键字个数在 30-50 之间的编程语言共有 9 个;关键字个数低于 30 的编程语言有 4 个,其中最少的是 Elixir,只有 15 个关键字。


参考链接:


https://github.com/bdrung/startup-time


https://github.com/e3b0c442/keywords


2019-08-28 10:1016443
用户头像

发布了 497 篇内容, 共 341.4 次阅读, 收获喜欢 1927 次。

关注

评论 2 条评论

发布
用户头像
InfoQ 日常黑 Go。。。
2019-08-28 19:42
回复
用户头像
哗众取宠呀,使用gccgo编译go,怎么会不慢呢?
2019-08-28 10:32
回复
没有更多了
发现更多内容

WWDC22 开发者需要关注的重点内容

37手游iOS技术运营团队

iOS16 WWDC22 Xcode14 iPadOS16 macOS10.16

什么是Vue3的组合式 API?

源字节1号

软件开发 小程序开发

模块八作业

库尔斯

#架构实战营

LabVIEW控制Arduino实现超声波测距(进阶篇—5)

不脱发的程序猿

单片机 LabVIEW Arduino VISA 超声波测距

flutter系列之:flutter中常用的container layout详解

程序那些事

flutter 程序那些事 6月月更

动态规划之0-1背包问题(详解+分析+原码)

未见花闻

6月月更

volatile的解构

卢卡多多

volatile 6月月更

预解析与作用域

Jason199

js 全局作用域 作用域 6月月更

BottomSheetDialog 使用详解,设置圆角、固定高度、默认全屏等

yechaoa

android dialog 6月月更 material design

【Spring 学习笔记(十)】Spring 使用注解整合 Mybatis

倔强的牛角

Java spring Java EE 6月月更

谈谈远程工作 | 社区征文

大菠萝

初夏征文

向线程池提交任务

急需上岸的小谢

6月月更

直播预告|FeatureStore Meetup V3 重磅来袭!

星策开源社区

机器学习 开源 DevOps 特征平台 MLOps

【Python技能树共建】lxml 模块

梦想橡皮擦

Python 6月月更

Flutter doctor 显示xcode没有安装的解决办法

坚果

6月月更

为什么需要微服务

阿泽🧸

微服务 6月月更

vue自定义指令

小恺

6月月更

数据库每日一题---第9天:销售员

知心宝贝

数据库 算法 前端 后端 6月月更

LabVIEW Arduino电子称重系统(项目篇—1)

不脱发的程序猿

单片机 LabVIEW VISA ​Arduino Uno 电子称重系统

消息队列入门MQ

卢卡多多

MQ 消息队列 6月月更

【愚公系列】2022年06月 面向对象设计原则(六)-合成复用原则

愚公搬代码

6月月更

一文读懂Logstash原理

恒山其若陋兮

6月月更

消息队列存储消息数据的 MySQL表

Dean.Zhang

思科私有动态路由协议:EIGRP

wljslmz

动态路由 6月月更 路由协议 EIGRP

5分钟了解攻防演练中的红蓝紫

穿过生命散发芬芳

6月月更 攻防演练

Java—并发容器

武师叔

6月月更

基于华为云图像识别标签实战

乌龟哥哥

6月月更

LabVIEW控制Arduino实现红外测距(进阶篇—6)

不脱发的程序猿

单片机 LabVIEW VISA Arduino Uno 红外测距

leetcode 257. Binary Tree Paths 二叉树的所有路径(简单)

okokabcd

LeetCode 搜索 数据结构与算法

RF中使用reuqests的两种方式

红毛丹

Python 6月月更

ConcurrentHashMap 源码分析-put方法

zarmnosaj

6月月更

有趣的编程语言:Go 语言的启动时间是 C 语言的300多倍,C# 的关键字最多_语言 & 开发_田晓旭_InfoQ精选文章