关于哪种语言速度执行速度最快,画了张图表,顺带吐槽

2021-05-16 05:48:27 +08:00
 LeeReamond

起因:昨天论坛老哥分享 Python 性能提升计划,其中一些涉及性能的讨论,27 楼老哥自己画了个图表看起来挺不错的。原贴链接

我个人是因为对 python 性能提升很感兴趣,对其他语言的语言性能比较也很感兴趣,有大版本更新的时候都会搞一些简单算法看看到底快了多少。这回看到这个老哥的图感觉挺不错的,该老哥称自己定期爬取 the benchmarks ganme 画出来的图,我感觉不如直接搞成一个自动维护项目,以后也省得手贱再自己动手跑了。

鼓捣了一下,大概思路就是基于 github 的分发特性,一个图片链接可以一直保持在最新数据,然后我在原版数据的基础上添加了两个 python 的 jit 解释器( pypy 和 pyston ),最后结果如下:

数据来源 https://benchmarksgame-team.pages.debian.net/benchmarksgame/index.html

=====================

几点说明:

1 、语言性能讨论一直是引战话题,我不是很理解为什么有人会在这个问题上被摸到 G 点,为了避免被喷,我先声明我这个不是严谨性能测试,只是基于开源跑分的爬虫并绘制图表而已。这个项目产生的原因是希望为需要的人提供一些定性结论(或者是定性结论的参考,毕竟它有可能不准),而不是严谨的定量结论。

2 、以前虽然跟别人讨论经常引用 the benchmarks game 的结论,但从来没仔细研究过这个网站。这次顺带仔细看了一下算法,我觉得它这些设计有几个可能本身也并不严谨。本身对比语言性能就是很难设计的一件事,理解。

3 、我在做这张图表的时候遇到一个统计学问题,由于一张图里要汇总多项测试的平均水平,一个最简单的想法是求平均耗时。但是需要考虑到一种极端情况就是,假设大部分测试都以非常短的耗时(比如 10 秒以内)完成,而个别测试极端情况的项目的总体时间消耗都很高(比如超过 600 秒),那么如果单纯做加和的话,整体的平均值会很大程度上取决于这个极端情况的结果,而削减了其他项目的影响力,为了避免这种情况发生,需要对数据加权。

我的方案是采用了如下图所示的运算得到最终结果,其中σ是方差,L 是常数,V 代表输出值。

大体思路就是,当一个项目整体测试时间较长的时候,我们会略微削弱这个项目的权重,让他不要影响那么大。同时考虑到如果用离散度描述整体测试时间的跨度,方差的比例差可能是一个非常大的数,所以需要进行某种压限,以确保权重最低的项目不会比权重最高的项目低出太多。算法是拍脑袋想的,有兴趣的欢迎看源码,或提意见。

4 、the benchmarks game 这个网站算是比较熟了,隔一段时间总会看到,但是说实话这次跑出来比例挺多反常识的,大概有以下几点:

我后面手动检查了一下数据,应该不是我写错了,确实测试结果加权平均算下来就是这样的,可能是由于这个跑分本身也没那么严谨,或者是特定语言在一些大量使用场景(比如正则)有让效率接近原生级的优化所导致的。

6375 次点击
所在节点    分享创造
44 条回复
Cbdy
2021-05-16 12:59:50 +08:00
其实很合理,不是 Go 慢,而是 JavaScrip/V8 快,而做 V8 的人以前是做 JVM 的,就很合理了
zagfai
2021-05-16 13:24:38 +08:00
有啥意义??
missdeer
2021-05-16 13:36:45 +08:00
C++比 C 快出乎我的意料
最近我观察到 C++写的 notepad++在冷加载时往往很慢,但是 C 写的 notepad2 任何时候都很快(它貌似还有汇编级的指令集优化),我就以为随手写的 C 比随手写的 C++要快不少
xinyana
2021-05-16 14:26:26 +08:00
不太关心快不快,实现功能就行
chaowang
2021-05-16 14:43:33 +08:00
我也好奇,为啥 cpp 比 c 还快
des
2021-05-16 15:01:30 +08:00
toptyloo
2021-05-16 15:02:12 +08:00
java 不考虑启动 JVM 确实是很快的。
ipwx
2021-05-16 15:09:03 +08:00
@pkookp8 C++ 追求的 zero-cost abstract,template 大法超级给力。

举个例子,std::sort(vec.begin(), vec.end(), [&](const auto& lhs, const auto& rhs) { return lhs < rhs; });

这里的比较器直接被 C++ 编译器内联了(开 -O2 )。如果是 C 语言版本的快排:

bool fn(const void* a, const void *b)
qsort(..., &fn);

函数指针丢进去。除非给每个函数写特殊规则(比如 qsort 是库函数说不定还有机会),一般函数根本没有内联优化的可能性。

====

再比如 C++ 17 的各种骚操作,例如:

inline constexpr size_t pow2(int n) { return n == 0 ? 1 : 2 * pow2(n-1); }

...

template <int N>
if constexpr (pow2(N) > 1024) {
... branch A
} else {
... branch B
}

这段代码,pow2 和 constexpr 都是编译期就确定的行为,不会在运行时计算。
jhdxr
2021-05-16 15:11:08 +08:00
@des 我倒不认为是 jit 的原因,php 本身实现的时候就用了不少 trick 去提升性能(举个栗子,在编译期间,部分热点函数的调用,会被替换为一些(专门针对这些函数编写的) opcode ),但这种 trick 是好是坏就见仁见智了。。。


@SuperMild V8 作为解释型能那么快我还是很震惊的。就算 JIT 也不可能转换所有代码。
ipwx
2021-05-16 15:12:52 +08:00
@missder @chaowang C++ 的一些评论见我上面的楼。

另外编辑器的问题,我觉得是作者设计上和实现上偷懒了。C++ 最快的写法写起来还挺累人的,各种奇迹淫巧那不是炫技,而是用了就比 C 快,不用就比 C 慢很多。我写 C++ 经常不开优化比开优化慢 5 ~ 10 倍。

另外面向优化写代码必须消除 warning,任何 C++ 标准未定义行为都要绕道走。网上不也很多段子,什么什么公司的代码一开优化就崩溃么 2333 。
3dwelcome
2021-05-16 15:18:26 +08:00
楼上打那么多字是认真的吗?
楼主链接有提供源代码,花十秒点进去看一下,就知道为什么 c++比 c 快了。
就是一个用了 simd 指令,另一个没用。
marcushbs
2021-05-16 15:23:04 +08:00
Ruby 3 jit 出来好久了,就没人想起来更新一下
matrix67
2021-05-16 15:24:47 +08:00
有没有最赚钱的语言排行,单位行数赚钱比
Jooooooooo
2021-05-16 15:53:47 +08:00
java 没有 jit 基本没法用
namelosw
2021-05-16 16:26:23 +08:00
Node.js 是个狠人啊…
LeeReamond
2021-05-16 16:29:59 +08:00
@marcushbs 我这个项目可以自己加解释器,新增加语言不太行,因为需要自己实现算法,新加解释器比较简单,有需要欢迎 pr
LeeReamond
2021-05-16 16:32:50 +08:00
@des 因为他原版已经画了这种图了,再画一遍意义不大,而且我希望我各个项目能提供直观结论,一眼能看出差多少倍那种的
LeeReamond
2021-05-16 16:35:46 +08:00
@hronro 我的想法是如果做图的人自己都没有结论,还需要用户去自行筛选,那失去了简明的初衷,如果算法有问题可以修改算法,不应该做两个版本留给用户
akira
2021-05-16 17:30:46 +08:00
原生 快于 解释
chengxiao
2021-05-17 09:55:00 +08:00
.net 和 java 先把虚拟机去了再跟人比较快慢吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/777179

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX