Ruby自身方法的表现

时间:2016-05-25 16:23:03

标签: ruby performance

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

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

我很想知道,由于Ruby自己的方法减少了太多的样板,它们实际上可能很慢。但鉴于Ruby是用C语言编写的,它对速度/性能有相当大的影响吗? (在有很多此类陈述的程序中)

3 个答案:

答案 0 :(得分:3)

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

puts 1000

但你也可以写下任何一个:

  • puts 1_000
  • puts 0b1111101000
  • puts 01750

这些都是一样的。不是"相同"因为他们产生了相同的结果,但同样的"就像在Ruby中解析并以完全相同的方式执行它们。它们的语法不同,但它们的语义是相同的。

对于Ruby的不同数组语法(以及它的等效字符串语法,Regexp文字等)也是如此。您可以使用Ruby的--dump insns(转储指令序列)选项自行测试:

$ 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
$ 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:

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

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

  1. (0002)将字符串"a"推到堆栈顶部。
  2. (0004)将字符串"b"推到堆栈顶部。
  3. (0006)从堆栈中弹出前两个值,从中创建一个数组并将其推入堆栈。
  4. 这些是MRI VM在两种情况下都会执行的实际指令。 Ruby永远不会知道您使用%w( ... )而不是[ ... ],并且没有其他代码可以执行。

答案 1 :(得分:1)

部分 MRI Ruby 用C语言编写,其余部分用Ruby编写。一些 JRuby 是用Java编写的,其余部分用Ruby编写。

Ruby是一种非常棒的语言,但它可能比其他语言慢,尤其是Java和C等低级语言。

Ruby的优势不在于运行时性能,而在于开发的清晰度,表现力,简洁性和速度。

这个问题没有一个答案,因为每种情况的成本和收益的计算都有自己的输入,它自身的权重对每个备选方案的优势的相对重要性;它自己的代码组合可能会或可能不会受到Ruby速度较慢的影响。当然,您需要对代码进行基准测试,以确定差异是否明显 - 可能不是。

我(我认为大多数或所有Rubyist)认为在大多数情况下速度上的差异不够大或不足以激励我们放弃Ruby而转向另一种语言。

答案 2 :(得分:1)

我只想补充一下,如果你想运行一些测试来比较你应该看看Benchmark模块的速度:http://ruby-doc.org/stdlib-1.9.3/libdoc/benchmark/rdoc/Benchmark.html