Ruby 红宝石基准不规则岩的来源

Ruby 红宝石基准不规则岩的来源,ruby,performance,benchmarking,Ruby,Performance,Benchmarking,运行此代码: require 'benchmark' Benchmark.bm do |x|   x.report("1+1") {15_000_000.times {1+1}}   x.report("1+1") {15_000_000.times {1+1}}   x.report("1+1") {15_000_000.times {1+1}}   x.report("1+1") {15_000_000.times {1+1}}   x.report("1+1") {15_000_000.

运行此代码:

require 'benchmark'

Benchmark.bm do |x|
  x.report("1+1") {15_000_000.times {1+1}}
  x.report("1+1") {15_000_000.times {1+1}}
  x.report("1+1") {15_000_000.times {1+1}}
  x.report("1+1") {15_000_000.times {1+1}}
  x.report("1+1") {15_000_000.times {1+1}}
end
输出这些结果:

       user     system      total        real
1+1  2.188000   0.000000   2.188000 (  2.250000)
1+1  2.250000   0.000000   2.250000 (  2.265625)
1+1  2.234000   0.000000   2.234000 (  2.250000)
1+1  2.203000   0.000000   2.203000 (  2.250000)
1+1  2.266000   0.000000   2.266000 (  2.281250)

猜测变异是系统环境的结果,但想确认这一点。

“猜测变异是系统环境的结果”,您是对的


基准不可能总是精确的。你没有一台完美的常规机器可以在同一时间运行某些东西。从基准测试中选取两个相同的数字,如果它们太接近,就像在本例中一样。

我尝试使用
eval
来部分展开循环,虽然它使循环速度更快,但它使执行时间不太一致

$VERBOSE &&= false # You do not want 15 thousand "warning: useless use of + in void context" warnings
# large_number = 15_000_000 # Too large! Caused eval to take too long, so I gave up
somewhat_large_number = 15_000
unrolled = "def do_addition\n" + ("1+1\n" * somewhat_large_number) + "end\n" ; nil
eval(unrolled)

require 'benchmark'

Benchmark.bm do |x|
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
end
为了进行比较,您在我的计算机上的基准测试给出了

      user     system      total        real
1+1  2.406000   0.000000   2.406000 (  2.406497)
1+1  2.407000   0.000000   2.407000 (  2.484629)
1+1  2.500000   0.000000   2.500000 (  2.734655)
1+1  2.515000   0.000000   2.515000 (  2.765908)
1+1  2.703000   0.000000   2.703000 (  4.391075)

(在最后一行中实时变化,但不是用户或总数)

“猜测变化是系统环境的结果”,您是对的。@LBg:谢谢,请随意将其作为答案发布。@Grimm:我很困惑,您所做的更改似乎比发布的代码慢。这意味着你的代码太慢了,无法处理添加“1+1”1500万次。我发布的代码的稳定性和运行时与您发布的代码有很大的不同。你们唯一能向我证明的是基准测试有多不稳定。我错过什么了吗?我想我最不明白的是你的答案和我的问题有什么关系。意识到你花了时间思考这个问题,我只是觉得我没有抓住你的重点。谢谢@错误:我不能让
do_addition
包含1500万个添加项,所以我让它包含15000个添加项,并调用了1000次。15_000*1000==15_000_000。@格林:你的答案是针对什么问题的?我发布的问题基本上是,是否有人能确认基准测试结果只与运行环境一样稳定。该代码只是作为易于阅读的概念证明提供的,并且可以看到结果是不稳定的。
      user     system      total        real
1+1  2.406000   0.000000   2.406000 (  2.406497)
1+1  2.407000   0.000000   2.407000 (  2.484629)
1+1  2.500000   0.000000   2.500000 (  2.734655)
1+1  2.515000   0.000000   2.515000 (  2.765908)
1+1  2.703000   0.000000   2.703000 (  4.391075)