在下面的红宝石代码中,' eval'比“def”慢10倍。
我理解' eval'需要解析字符串,但我想在这个例子中只需要完成一次。
require "benchmark"
GC.disable
eval "def run1; 10_000.times { #{"$a[5]\n" * 10_000} } end"
def run2
10_000.times { "#{"$a[5]\n" * 10_000}" }
end
$a = [1,2,3,4,5,6,7,8,9,10]
puts "run1:"
puts Benchmark.measure { run1 }
puts "run2:"
puts Benchmark.measure { run2 }
答案 0 :(得分:7)
您没有比较等效函数。 run1
最终成为单个字符串中$a[5]\n
10,000次的函数,因为在调用eval
之前,字符串插值是在构建字符串时发生的。 run2
按照人们的预期运行。
要了解差异,请将ruby-prof
投入混音:
require "benchmark"
require 'ruby-prof'
GC.disable
eval "def run1; 10_000.times { #{"$a[5]\n" * 10_000} } end"
def run2
10_000.times { "#{"$a[5]\n" * 10_000}" }
end
$a = [1,2,3,4,5,6,7,8,9,10]
puts "run1:"
RubyProf.start
puts Benchmark.measure { run1 }
result = RubyProf.stop
printer = RubyProf::FlatPrinter.new(result)
printer.print(STDOUT)
puts "run2:"
RubyProf.start
puts Benchmark.measure { run2 }
result = RubyProf.stop
printer = RubyProf::FlatPrinter.new(result)
printer.print(STDOUT)
编辑:这是结果(我删除了Benchmark调用以将其修改为基础)
(nick@monster)-(~/Desktop)
(523)⚡️ ruby derp.rb
run1:
Thread ID: 2156059640
Fiber ID: 2163430960
Total: 484.962207
Sort by: self_time
%self total self wait child calls name
100.00 484.962 484.962 0.000 0.000 1 Integer#times
0.00 484.962 0.000 0.000 484.962 1 Global#[No method]
0.00 484.962 0.000 0.000 484.962 1 Object#run1
* indicates recursively called methods
run2:
Thread ID: 2156059640
Fiber ID: 2163430960
Total: 0.265188
Sort by: self_time
%self total self wait child calls name
94.02 0.249 0.249 0.000 0.000 10000 String#*
5.98 0.265 0.016 0.000 0.249 1 Integer#times
0.01 0.265 0.000 0.000 0.265 1 Global#[No method]
0.00 0.265 0.000 0.000 0.265 1 Object#run2
* indicates recursively called methods