新手问题 编程语言性能问题

ryanzhang · 2014年08月26日 · 最后由 shinefine 回复于 2014年08月26日 · 2580 次阅读

比如平时我们说某某语言比某某语言的性能好,到底是什么原因产生了这个性能差别?

帮程序员做的事情多与少

新手喜欢拿性能说事

越接近机器的语言,运行性能越好。抽象能力越高的语言,运行性能越差。

#2 楼 @bhuztez 跑分结果完全看 bench 怎么写的,benchmark 代码怎么写,怎么样算"做相同的事情"完全看写者偏好...

还没有遇到语言的性能问题,怎么破

觉得可以参考下别人解释为什么 Julia 非常快。 https://groups.google.com/d/msg/julia-users/Uu_UcYp49Qo/YKbwzUpgZzEJ

Julia 语法应该同 Octave,R 不相上下。速度接近 C http://julialang.org/

有些情况下,是没必要考虑运行速度的,有些情况下,却正好相反。

TL;DR

编译器/解释器与程序员之间的博弈,看把脏活给谁做。

Detail

简单说下 Ruby 吧。由于 Ruby 是动态语言,所以类型检查是放在运行时的,不像 C 等静态类型语言,在编译时就可以确定类型。

不要给我说 Ruby 是鸭子类型,那是 Ruby 层面,回到 CRuby 的实现层面,解释器需要对数据进行区分。CRuby 中的对象就是一个VALUE,根据 VALUE 是否为为特殊值QtrueQfalse等、VALUE是否为奇数判断是否为FIXNUM,然后再解释为RXXX的结构体。对于 C 来说,编译时做完类型检查就一劳永逸了,而 Ruby 却不得不在每次求值时做一次检查(为了知道这个VALUE是什么)。[之前貌似看到了说 Ruby 要引入静态类型?发帖前搜了下社区,好像是 Feature #9999,参见 Further Reading No.3]

再比如,C 语言里面的字符串是非常 Dirty 的,比较轻量的就是栈上的字符数组(临时变量),再大不了就是堆上的存储空间(malloc等分配),为了存储一个大小为 X 字节的字符串,至多需要 X+1 字节的空间(算上\0),编译器不带检查溢出,因为它认为那是“程序员的事儿”,所以编译器就非常省事儿了。Ruby 就不一样了。Ruby 的字符串在建立时就需要经过一些检查,而且为了高效利用内存,Ruby 按照自己的方法设计了数据结构(比如下面)。很明显,Ruby 中一个大小为 X 字节的字符串,需要远多于 X 字节的空间,不要忘了还有一个指向这个RString结构体的VALUE,占用了一个机器字!

struct RString {
      struct RBasic basic;
      long len;
      char *ptr;
      union {
          long capa;
          VALUE shared;
      } aux;
};

总而言之,你爽了,编译器/解释器就苦逼了。Dennis 把脏活推给程序员,Matz 让 Ruby 任劳任怨,各有各的道理。

B.T.W. 如果想深入了解 Ruby 语言背后的细节,《Ruby Hacking Guide》是一份非常棒的参考资料。或者学习《The Structure and Interpretation of Computer Program》的第四章和第五章,了解一下如何做一个求值器,你应该能对这个问题有深入体会的。

Reference

  1. 第二章:对象

Further Reading

  1. Ruby China | 好像 Ruby 的性能问题始终是个大问题啊! » 社区,尤其注意 101 楼@luikore 吕大师的回答,我的观点和他是一致的。
  2. 弱类型、强类型、动态类型、静态类型语言的区别是什么? - 知乎
  3. https://bugs.ruby-lang.org/issues/9999

简单来说,是因为语言的抽象层次 《黑客与画家》里面作者对此有所讨论。第十章:编程语言解析

#9 楼 @DeathKing 话说我是长答案爱好者,终于看到一个详细解释说明的,大赞!

需要 登录 后方可回复, 如果你还没有账号请 注册新账号