提到编程语言,大多数的文章内容都这样的: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 启动基准。
测试结果如下:
Language |
version |
Intel Core i5 2400S |
Raspberry Pi 3 |
Pascal (fpc) |
3.0.2 / 3.0.4 |
0.08 ms |
0.66 ms |
C (gcc) |
7.2.0 |
0.26 ms |
2.19 ms |
Shell (dash) |
0.5.8 |
0.33 ms |
2.81 ms |
Go (go) |
1.8.3 / 1.9.3 |
0.41 ms |
4.10 ms |
Rust (rustc) |
1.21.0 / 1.22.1 |
0.51 ms |
4.42 ms |
D (gdc) |
7.2.0 |
0.57 ms |
|
Lua |
5.2.4 |
0.63 ms |
6.23 ms |
Bash |
4.4.12(1) |
0.71 ms |
7.31 ms |
C++ (g++) |
7.2.0 |
0.79 ms |
8.24 ms |
Perl |
5.26.0 / 5.26.1 |
0.94 ms |
8.78 ms |
Haskell (ghc) |
8.0.2 |
0.72 ms |
9.44 ms |
ZShell |
5.2 / 5.4.2 |
1.57 ms |
11.04 ms |
CShell |
20110502 |
3.26 ms |
10.98 ms |
Python (with -S) |
2.7.14 |
2.91 ms |
32.77 ms |
Python |
2.7.14 |
9.43 ms |
91.85 ms |
PHP |
7.1.11 / 7.2.2 |
8.71 ms |
98.03 ms |
Cython |
0.25.2 / 0.26.1 |
9.91 ms |
98.71 ms |
Python3 (with -S) |
3.6.3 / 3.6.4 |
9.31 ms |
110.02 ms |
C# (mcs) |
4.6.2.0 |
13.37 ms |
137.53 ms |
PyPy |
5.8.0 |
27.53 ms |
183.50 ms |
Cython3 |
0.25.2 / 0.26.1 |
26.04 ms |
196.36 ms |
Python3 |
3.6.3 / 3.6.4 |
25.84 ms |
197.79 ms |
Ruby |
2.3.3p222 / 2.3.6p384 |
32.43 ms |
421.53 ms |
Java (javac) |
1.8.0_151 |
54.55 ms |
566.66 ms |
Go (gccgo) |
7.2.0 |
98.26 ms |
898.30 ms |
Scala (scalac) |
2.11.8 |
310.81 ms |
2989.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
auto |
break |
case |
char |
const |
continue |
default |
do |
double |
else |
enum |
extern |
float |
for |
goto |
if |
int |
long |
register |
return |
short |
signed |
sizeof |
static |
struct |
switch |
typedef |
union |
unsigned |
void |
volatile |
while |
C (C18) (44 keywords)
http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf
auto |
break |
case |
char |
const |
continue |
default |
do |
double |
else |
enum |
extern |
float |
for |
goto |
if |
inline |
int |
long |
register |
restrict |
return |
short |
signed |
sizeof |
static |
struct |
switch |
typedef |
union |
unsigned |
void |
volatile |
while |
_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
abstract |
as |
base |
bool |
break |
byte |
case |
catch |
char |
checked |
class |
const |
continue |
decimal |
default |
delegate |
do |
double |
else |
enum |
event |
explicit |
extern |
false |
finally |
fixed |
float |
for |
foreach |
goto |
if |
implicit |
in |
int |
interface |
internal |
is |
lock |
long |
namespace |
new |
null |
object |
operator |
out |
override |
params |
private |
protected |
public |
readonly |
ref |
return |
sbyte |
sealed |
short |
sizeof |
stackalloc |
static |
string |
struct |
switch |
this |
throw |
true |
try |
typeof |
uint |
ulong |
unchecked |
unsafe |
ushort |
using |
virtual |
void |
volatile |
while |
|
|
|
C++ (C++17) (73 keywords)
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf
alignas |
alignof |
asm |
auto |
bool |
break |
case |
catch |
char |
char16_t |
char32_t |
class |
const |
constexpr |
const_cast |
continue |
decltype |
default |
delete |
do |
double |
dynamic_cast |
else |
enum |
explicit |
export |
extern |
false |
float |
for |
friend |
goto |
if |
inline |
int |
long |
mutable |
namespace |
new |
noexcept |
nullptr |
operator |
private |
protected |
public |
register |
reinterpret_cast |
return |
short |
signed |
sizeof |
static |
static_assert |
static_cast |
struct |
switch |
template |
this |
thread_local |
throw |
true |
try |
typedef |
typeid |
typename |
union |
unsigned |
using |
virtual |
void |
volatile |
wchar_t |
while |
|
|
|
Dart (1) (33 keywords)
http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-408.pdf
assert |
break |
case |
catch |
class |
const |
continue |
default |
do |
else |
enum |
extends |
false |
final |
finally |
for |
if |
in |
is |
new |
null |
rethrow |
return |
super |
switch |
this |
throw |
true |
try |
var |
void |
while |
with |
|
|
|
Elixir (1.7) (15 keywords)
https://github.com/elixir-lang/elixir/blob/master/lib/elixir/pages/Syntax%20Reference.md
true |
false |
nil |
when |
and |
or |
not |
in |
fn |
do |
end |
catch |
rescue |
after |
else |
|
Erlang (21.2) (27 keywords)
http://erlang.org/doc/reference_manual/introduction.html#reserved-words
after |
and |
andalso |
band |
begin |
bnot |
bor |
bsl |
bsr |
bxor |
case |
catch |
cond |
div |
end |
fun |
if |
let |
not |
of |
or |
orelse |
receive |
rem |
try |
when |
xor |
|
Go (1.11) (25 keywords)
https://golang.org/ref/spec#Keywords
break |
case |
chan |
const |
continue |
default |
defer |
else |
fallthrough |
for |
func |
go |
goto |
if |
import |
interface |
map |
package |
range |
return |
select |
struct |
switch |
type |
var |
|
|
|
JS (ES2018) (34 keywords)
https://www.ecma-international.org/ecma-262/9.0/index.html#sec-keywords
await |
break |
case |
catch |
class |
const |
continue |
debugger |
default |
delete |
do |
else |
export |
extends |
finally |
for |
function |
if |
import |
in |
instanceof |
new |
return |
super |
switch |
this |
throw |
try |
typeof |
var |
void |
while |
with |
yield |
|
|
Java (SE 11) (51 keywords)
https://docs.oracle.com/javase/specs/jls/se11/html/jls-3.html#jls-3.9
abstract |
assert |
boolean |
break |
byte |
case |
catch |
char |
class |
const |
continue |
default |
do |
double |
else |
enum |
extends |
final |
finally |
float |
for |
if |
goto |
implements |
import |
instanceof |
int |
interface |
long |
native |
new |
package |
private |
protected |
public |
return |
short |
static |
strictfp |
super |
switch |
synchronized |
this |
throw |
throws |
transient |
try |
void |
volatile |
while |
|
|
Kotlin (1.3) (30 keywords)
https://kotlinlang.org/docs/reference/keyword-reference.html
as |
as? |
break |
class |
continue |
do |
else |
false |
for |
fun |
if |
in |
|
interface |
is |
|
null |
object |
package |
return |
super |
this |
throw |
true |
try |
typealias |
val |
var |
when |
while |
|
|
PHP (7.0) (67 keywords)
http://php.net/manual/en/reserved.keywords.php
__halt_compiler() |
abstract |
and |
array() |
as |
break |
callable |
case |
catch |
class |
clone |
const |
continue |
declare |
default |
die() |
do |
echo |
else |
elseif |
empty() |
enddeclare |
endfor |
endforeach |
endif |
endswitch |
endwhile |
eval() |
exit() |
extends |
final |
finally |
for |
foreach |
function |
global |
goto |
if |
implements |
include |
include_once |
instanceof |
insteadof |
interface |
isset() |
list() |
namespace |
new |
or |
print |
private |
protected |
public |
require |
require_once |
return |
static |
switch |
throw |
trait |
try |
unset() |
use |
var |
while |
xor |
yield |
|
Python (2.7) (31 keywords)
https://docs.python.org/2/reference/lexical_analysis.html#keywords
and |
as |
assert |
break |
class |
continue |
def |
del |
elif |
else |
except |
exec |
finally |
for |
from |
global |
if |
import |
in |
is |
lambda |
not |
or |
pass |
print |
raise |
return |
try |
while |
with |
yield |
|
Python (3.7) (35 keywords)
https://docs.python.org/3.7/reference/lexical_analysis.html#keywords
False |
None |
True |
and |
as |
assert |
async |
await |
break |
class |
continue |
def |
del |
elif |
else |
except |
finally |
for |
from |
global |
if |
import |
in |
is |
lambda |
nonlocal |
not |
or |
pass |
raise |
return |
try |
while |
with |
yield |
|
R (3.5) (20 keywords)
https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Reserved-words
… |
FALSE |
Inf |
NA |
NA_character_ |
NA_complex_ |
NA_integer_ |
NA_real_ |
NaN |
NULL |
TRUE |
break |
else |
for |
function |
if |
in |
next |
repeat |
while |
Ruby (2.5) (41 keywords)
https://docs.ruby-lang.org/en/2.5.0/keywords_rdoc.html
ENCODING |
LINE |
FILE |
BEGIN |
END |
alias |
and |
begin |
break |
case |
class |
def |
defined? |
do |
else |
elsif |
end |
ensure |
false |
for |
if |
in |
module |
next |
nil |
not |
or |
redo |
rescue |
retry |
return |
self |
super |
then |
true |
undef |
unless |
until |
when |
while |
yield |
|
|
|
Rust (1.31) (53 keywords)
https://doc.rust-lang.org/grammar.html#keywords
_ |
abstract |
alignof |
as |
become |
box |
break |
const |
continue |
crate |
do |
else |
enum |
extern |
false |
final |
fn |
for |
if |
impl |
in |
let |
loop |
macro |
match |
mod |
move |
mut |
offsetof |
override |
priv |
proc |
pub |
pure |
ref |
return |
Self |
self |
sizeof |
static |
struct |
super |
trait |
true |
type |
typeof |
unsafe |
unsized |
use |
virtual |
where |
while |
yield |
|
|
|
Scala (2.12) (40 keywords)
https://scala-lang.org/files/archive/spec/2.12/01-lexical-syntax.html
abstract |
case |
catch |
class |
def |
do |
else |
extends |
false |
final |
finally |
for |
forSome |
if |
implicit |
import |
lazy |
macro |
match |
new |
null |
object |
override |
package |
private |
protected |
return |
sealed |
super |
this |
throw |
trait |
try |
true |
type |
val |
var |
while |
with |
yield |
Swift (4.2) (70 keywords)
https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html
associatedtype |
class |
deinit |
enum |
extension |
fileprivate |
func |
import |
init |
inout |
internal |
let |
open |
operator |
private |
protocol |
public |
static |
struct |
subscript |
typealias |
var |
break |
case |
continue |
default |
defer |
do |
else |
fallthrough |
for |
guard |
if |
in |
repeat |
return |
switch |
where |
while |
as |
Any |
catch |
false |
is |
nil |
rethrows |
super |
self |
Self |
throw |
throws |
true |
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
未经允许不得转载:迪欧吧_技术交流_资源分享_热点资讯_免费VPS空间 » 有趣的编程语言统计:Go 语言的启动时间是 C 语言的 300 多倍,C# 的关键字最多 | 程序师 – 程序员、编程语言、软件开发、编程技术-迪欧吧