用Benchmark测试不同ruby代码的运行速度

如果比较功能相同的几组代码的运行速度, 可以使用ruby语言里的Benchmark模块.
(开始前 设置中文环境, $KCODE = ‘u’)
比如, 连接两个字串, 如:
str1 = "中国"
str2 = "一定强!!!"

可以使用+
?> str1 + str2
=> "中国一定强!!!"
也可使用
>> "#{str1}#{str2}"
=> "中国一定强!!!"
还可以使用<<
>> str1 << str2
=> "中国一定强!!!"
(注意这种方法会改变str1的值,
>> str1
=> "中国一定强!!!")

如果想要知道这三种方法哪一个速度更快, 就可以使用Benchmark比较.
先定义三个不同的方法:

def joined_by_plus(str_a, str_b)
    500000.times do; str_a.dup + str_b; end
end

def joined_by_uniting(str_a, str_b)
    500000.times do; "#{str_a.dup}#{str_b}"; end
end

def joined_by_adding(str_a, str_b)
    500000.times do; str_a.dup << str_b; end
end

因为这三种方法速度都很快, 比较一次的时间很难分出上下, 所以每种方法都做500000次.
因为<< 会改变变量, 所以在第三个方法中使用了str_a.dup, 备份出一个str_a来测试, 其它二个方法虽然从理论上不须要这个dup, 但为了时间上的公平, 也给它们加上了.

下面是测试代码:
require ‘benchmark’

Benchmark.bmbm(10) do |t|
  t.report(‘加号连接’) { joined_by_plus(str1, str2) }
  t.report(‘放进引号’) { joined_by_uniting(str1, str2)}
  t.report(‘使用<<’) { joined_by_adding(str1, str2)}
end

bmbm是Benchmark的测试方法, 这是双重测试, 用来提高精确度. 里面参数10用来调节标签在结果里的显示占位宽度, 不对结果产生影响.
report(‘加号连接’)里的参数是为相应测试的标签名, 用来区别测试结果.

下面就是结果:

Rehearsal ————————————————
加号连接   1.800000   0.580000   2.380000 (  2.435614)
放进引号   2.080000   0.590000   2.670000 (  2.706669)
使用<<       2.000000   0.580000   2.580000 (  2.635540)
————————————— total: 7.630000sec

                   user     system      total        real
加号连接   1.810000   0.600000   2.410000 (  2.476613)
放进引号   2.050000   0.600000   2.650000 (  2.656080)
使用<<       1.960000   0.600000   2.560000 (  2.567434)

因为使用了bmbm方式, 所以会有两个结果, 第一个是演习结果, 第二个是真实结果.  如果使用bm方法, 将只会有一组结果.
结果有user时间, 系统时间, 总时间和实际花费的时间. 单位为秒.

从结果可以看出, 使用+连接两个字串时速度最快, 而放进引号的方法最慢. 不过从结果也可以看出即使进行500000执行的结果也相差在0.3秒之内, 平时换用问题不大.

看来不是这一次, 希望下次你在自己的Benchmark试验中, 会发现给你的程序带来巨大速度提供的代码.

转载请注明: 转自船长日志, 本文链接地址: http://www.cslog.cn/Content/ruby_benchmark/

此条目发表在 Ruby on Rails 分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>