Ruby自己的方法的性能

Performance of Ruby's own methods

我在浏览Ruby上的数组时,遇到了一个创建数组的方法(可能还有更多方法)。

1
arr1 = %w(first second third) # => ["first","second","third"]

我想知道,既然Ruby自己的方法减少了这么多样板文件,那么它们实际上可能很慢。但是考虑到Ruby是用C语言编写的,它是否对速度/性能有相当大的影响?(在一个有很多这样陈述的程序中)


正如@thetinman在评论中提到的,您必须理解语言(语法)和逻辑(语义)之间的区别。例如,假设有人要求您编写一个打印数字1000的程序。你可能会这样写:

1
puts 1000

但你也可以写下这些:

  • puts 1_000
  • 江户十一〔一〕号
  • 埃多克斯1〔2〕

这些都是一样的。与中的"相同"不同,它们产生相同的结果,但与Ruby中的"相同"解析和执行它们的方式完全相同。它们的语法不同,但语义相同。

Ruby的不同数组语法(以及其等效的字符串语法、regexp文本等)也是如此。您可以使用Ruby的--dump insns选项(转储指令序列)自己测试:

1
2
3
4
5
6
7
8
9
10
11
$ ruby --dump insns -e 'arr = ["a","b"]'
== disasm: <RubyVM::InstructionSequence:<main>@-e>======================
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] arr
0000 trace            1                                               (   1)
0002 putstring       "a"
0004 putstring       "b"
0006 newarray         2
0008 dup
0009 setlocal_OP__WC__0 2
0011 leave

1
2
3
4
5
6
7
8
9
10
11
$ ruby --dump insns -e 'arr = %w(a b)'
== disasm: <RubyVM::InstructionSequence:<main>@-e>======================
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] arr
0000 trace            1                                               (   1)
0002 putstring       "a"
0004 putstring       "b"
0006 newarray         2
0008 dup
0009 setlocal_OP__WC__0 2
0011 leave

完全相同。当然,最重要的说明是0002-0006:

1
2
3
0002 putstring       "a"
0004 putstring       "b"
0006 newarray         2

这些说明说(或多或少):

  • (0002)将串"a"推到堆栈顶部。
  • (0004)将串"b"推到堆栈顶部。
  • (0006)从堆栈中弹出前两个值,从中创建一个数组并将其推到堆栈中。
  • 这是MRI虚拟机在两种情况下执行的实际指令。Ruby永远不知道您使用了%w( ... )而不是[ ... ],而且它不需要执行额外的代码。


    如果您想运行一些测试来比较基准测试模块的速度,我将补充一点:http://ruby-doc.org/stdlib-1.9.3/libdoc/benchmark/rdoc/benchmark.html。


    有些mri Ruby是用C编码的,其余的则是Ruby。有些JRuby是用Java编码的,其余的则用Ruby编码。

    露比是一种令人敬畏的语言,但它可能比其他语言慢,尤其是像Java和C这样的低级语言。

    Ruby的长处不是运行时性能,而是开发的清晰性、表达性、简洁性和速度。

    没有人回答这个问题,因为每种情况的成本和收益的计算都有自己的输入,每种选择的优势的相对重要性有自己的权重,以及可能或可能不受Ruby较慢速度影响的代码组合。当然,您需要对您的代码进行基准测试,以查看差异是否甚至是显著的——可能不是。

    我(而且我认为大多数或者所有的鲁比派)相信,在大多数情况下,速度上的差异不足以或不足以激励我们放弃鲁比而选择另一种语言。