Why 'eval' in ruby is so slow? -
in ruby code below, 'eval' more 10 times slower 'def'.
i understand 'eval' needs parse string, suppose needs done once in example.
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 }
you're not comparing equivalent functions. run1
ends being function $a[5]\n
10,000 times in single string, since string interpolation happens string built, before eval
called. run2
runs 1 expect.
to see difference, toss ruby-prof
mix:
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)
edit: here results (i removed benchmark calls prune down basics)
(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
Comments
Post a Comment