距离上一次 swapview 的更新已经一年多了。在这段时间里,不少语言有了比较大的更新,所以再跑一次。
首先是运行不了或者有问题的语言和实现:
-
Julia: 新版本不向后兼容,运行不了。求修。
-
Nim: 标准库有些函数的行为有改变:walkFiles 不再返回目录文件,split 不再将连续的空白符作为一个分隔符。
-
Erlang: 不再支持 ~.0f 格式化字符串。
其中不向后兼容的,Julia 和 Nim 还没到达 1.0 版,所以坑人了也就坑了。Erlang 不知道是怎么回事。
然后是有警告的:
-
R: 文件打开失败有警告。不是大问题,不过有点烦。如果你知道怎么去掉它,请告诉我。
-
Elixir: 函数无参调用时不加括号会触发警告。看来 Elixir 也不喜欢 Ruby 函数调用不加操作的行为了呢。
还有发行版的锅:
我还对代码做了一些改进:
-
Rust_parallel: 用 rayon 换掉了 threadpool。rayon 更适合这种并行任务处理。另外稍微改进了一下代码。
-
NodeJS: 使用 ECMAScript 6 语法(箭头函数和 const / let 变量声明)。去掉不必要的分号。
-
C: 支持 Android 平台。
-
修正了一些实现的格式化输出(还剩下一些)。
最后结果如下。因为 CPU 换成了 i7-7700HQ,所以耗时都比之前少了不少。另外注意,前排几名只有前三名都是多线程的,所以 Go_goroutine 比那些 C 和 C++ 版本快很正常。
Rust_parallel: top: 30.48, min: 27.76, avg: 32.48, max: 37.80, mdev: 2.78, cnt: 20
C++98_omp: top: 31.24, min: 29.04, avg: 34.42, max: 49.48, mdev: 4.52, cnt: 20
Go_goroutine: top: 68.30, min: 61.87, avg: 75.89, max: 142.91, mdev: 16.39, cnt: 20
C++14: top: 83.17, min: 82.23, avg: 84.71, max: 92.58, mdev: 2.76, cnt: 20
C++14_boost: top: 83.58, min: 83.20, avg: 84.58, max: 91.00, mdev: 1.72, cnt: 20
C++98: top: 83.71, min: 83.09, avg: 85.19, max: 91.48, mdev: 2.44, cnt: 20
Rust: top: 91.45, min: 90.81, avg: 93.08, max: 99.38, mdev: 2.07, cnt: 20
C: top: 91.49, min: 90.49, avg: 93.41, max: 99.44, mdev: 2.53, cnt: 20
C++11: top: 91.81, min: 91.33, avg: 93.52, max: 102.80, mdev: 3.04, cnt: 20
PHP: top: 93.91, min: 93.37, avg: 94.98, max: 99.42, mdev: 1.47, cnt: 20
OCaml: top: 106.85, min: 105.75, avg: 109.34, max: 118.03, mdev: 3.37, cnt: 20
Nim: top: 109.28, min: 108.44, avg: 110.75, max: 117.43, mdev: 2.13, cnt: 20
D_parallel_llvm: top: 111.25, min: 109.43, avg: 113.21, max: 117.26, mdev: 2.33, cnt: 20
D_parallel: top: 116.77, min: 114.69, avg: 118.95, max: 125.45, mdev: 2.87, cnt: 20
PyPy: top: 126.23, min: 124.29, avg: 128.34, max: 134.07, mdev: 2.79, cnt: 20
D_llvm: top: 129.63, min: 128.52, avg: 131.32, max: 137.65, mdev: 2.41, cnt: 20
LuaJIT: top: 132.68, min: 131.31, avg: 134.36, max: 143.07, mdev: 2.57, cnt: 20
Go: top: 135.57, min: 132.37, avg: 139.25, max: 148.37, mdev: 4.50, cnt: 20
D: top: 146.30, min: 145.00, avg: 149.14, max: 159.02, mdev: 3.85, cnt: 20
Haskell2: top: 150.92, min: 149.41, avg: 153.25, max: 164.60, mdev: 3.53, cnt: 20
Python2: top: 155.36, min: 152.26, avg: 158.55, max: 170.20, mdev: 4.60, cnt: 20
Vala: top: 159.55, min: 157.87, avg: 161.40, max: 166.52, mdev: 2.26, cnt: 20
Erlang: top: 163.00, min: 158.63, avg: 168.76, max: 181.77, mdev: 7.09, cnt: 20
Lua51: top: 166.58, min: 164.58, avg: 168.89, max: 181.71, mdev: 3.69, cnt: 20
Lua52: top: 168.48, min: 167.40, avg: 170.82, max: 178.11, mdev: 3.36, cnt: 20
Python3_bytes: top: 174.30, min: 172.65, avg: 176.83, max: 181.64, mdev: 2.91, cnt: 20
Lua53: top: 180.20, min: 177.79, avg: 185.01, max: 199.41, mdev: 6.07, cnt: 20
Perl: top: 180.22, min: 177.30, avg: 182.21, max: 186.09, mdev: 2.44, cnt: 20
FreePascal: top: 180.85, min: 179.35, avg: 184.23, max: 197.83, mdev: 4.84, cnt: 20
Python3: top: 181.72, min: 178.47, avg: 184.09, max: 189.67, mdev: 2.99, cnt: 20
Ruby: top: 199.82, min: 197.16, avg: 203.62, max: 218.32, mdev: 4.92, cnt: 20
Chicken: top: 234.69, min: 232.11, avg: 239.61, max: 248.39, mdev: 5.63, cnt: 20
PyPy3_bytes: top: 238.55, min: 237.18, avg: 242.08, max: 253.68, mdev: 4.53, cnt: 20
Guile: top: 254.49, min: 249.14, avg: 260.40, max: 275.83, mdev: 7.12, cnt: 20
ChezScheme: top: 265.63, min: 262.52, avg: 268.56, max: 278.53, mdev: 3.94, cnt: 20
Java: top: 291.35, min: 283.94, avg: 302.36, max: 324.82, mdev: 12.38, cnt: 20
NodeJS: top: 317.01, min: 314.61, avg: 321.04, max: 332.05, mdev: 4.71, cnt: 20
Dart: top: 329.39, min: 325.63, avg: 334.57, max: 351.19, mdev: 6.92, cnt: 20
Ruby_rubinius: top: 359.76, min: 357.74, avg: 363.13, max: 373.02, mdev: 4.45, cnt: 20
CommonLisp_opt: top: 360.57, min: 358.41, avg: 365.15, max: 378.44, mdev: 5.76, cnt: 20
Tcl: top: 367.38, min: 363.28, avg: 372.89, max: 388.57, mdev: 6.65, cnt: 20
CommonLisp_old: top: 376.27, min: 371.99, avg: 379.66, max: 390.55, mdev: 4.33, cnt: 20
PyPy3: top: 384.12, min: 376.60, avg: 390.16, max: 401.39, mdev: 7.32, cnt: 20
CoffeeScript: top: 414.40, min: 393.13, avg: 432.25, max: 466.42, mdev: 20.64, cnt: 20
CoffeeScript_parallel: top: 451.12, min: 425.11, avg: 464.92, max: 491.52, mdev: 17.05, cnt: 20
NodeJS_async: top: 454.78, min: 437.13, avg: 465.18, max: 489.06, mdev: 13.02, cnt: 20
Racket_compiled: top: 510.97, min: 505.22, avg: 516.20, max: 527.69, mdev: 6.23, cnt: 20
Racket: top: 520.70, min: 515.11, avg: 525.28, max: 533.79, mdev: 5.87, cnt: 20
NodeJS_parallel: top: 673.38, min: 664.38, avg: 687.60, max: 724.04, mdev: 16.32, cnt: 20
Scala: top: 719.27, min: 698.23, avg: 740.32, max: 815.95, mdev: 27.27, cnt: 20
Bash_parallel: top: 769.14, min: 751.56, avg: 775.91, max: 791.40, mdev: 8.82, cnt: 20
Haskell: top: 1036.33, min: 1013.27, avg: 1048.70, max: 1090.21, mdev: 4186.25, cnt: 20
Elixir: top: 1097.32, min: 1075.24, avg: 1113.36, max: 1144.80, mdev: 4186.26, cnt: 20
R: top: 1141.37, min: 1120.69, avg: 1156.42, max: 1177.79, mdev: 4186.26, cnt: 20
Bash: top: 1368.00, min: 1323.22, avg: 1479.66, max: 1994.19, mdev: 4077.71, cnt: 20
POSIX_dash: top: 1841.09, min: 1833.25, avg: 1851.09, max: 1881.68, mdev: 3897.64, cnt: 17
POSIX_zsh: top: 2124.79, min: 2110.81, avg: 2134.32, max: 2156.40, mdev: 3841.56, cnt: 15
POSIX_bash: top: 2200.64, min: 2195.09, avg: 2206.75, max: 2221.41, mdev: 3807.09, cnt: 14
CSharp: FAILED with entity not found
Julia: FAILED with entity not found
对比旧结果,可以看到有一些比较大的变化:
Rust 快了不少,并行版一跃成为最快的实现。C++98 OpenMP 版紧随其后。Rust 单线程版也上升了四名,与 C、C++ 版本接近,并超越了所有的 D 实现。Go 并行版也提升了不少,位居第三,但它花费的时间比前两名所花费时间的总和还要多……并且结果也不是很稳定(标准差比前二十名都要大不少)。
Nim 慢了不少,可能是因为没字符串分割函数可用,我改用了 pegs。这东西很慢的样子,也许正则还会快一点……C 也落后了一些,但是与 C++ 版本的差距不大。Haskell 大概是因为改用动态链接的原因,慢了少许。
PyPy 快了很多,竟然超越了 LuaJIT。Erlang、Guile、Rubinius 也都大幅上升,而 NodeJS 不知道怎么了,全面落后于 Python、Ruby、Lua。PHP 更新到 7 之后依旧非常非常快。
完整的排名变化可以看这里。