比如平时我们说某某语言比某某语言的性能好,到底是什么原因产生了这个性能差别?
觉得可以参考下别人解释为什么 Julia 非常快。 https://groups.google.com/d/msg/julia-users/Uu_UcYp49Qo/YKbwzUpgZzEJ
Julia 语法应该同 Octave,R 不相上下。速度接近 C http://julialang.org/ 。
有些情况下,是没必要考虑运行速度的,有些情况下,却正好相反。
编译器/解释器与程序员之间的博弈,看把脏活给谁做。
简单说下 Ruby 吧。由于 Ruby 是动态语言,所以类型检查是放在运行时的,不像 C 等静态类型语言,在编译时就可以确定类型。
不要给我说 Ruby 是鸭子类型,那是 Ruby 层面,回到 CRuby 的实现层面,解释器需要对数据进行区分。CRuby 中的对象就是一个VALUE
,根据 VALUE 是否为为特殊值Qtrue
、Qfalse
等、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》的第四章和第五章,了解一下如何做一个求值器,你应该能对这个问题有深入体会的。