require 'benchmark'

Benchmark.bm do |bm|
  bm.report("block:   gen 10,000,000 times        ") { (1..10_000_000).each {|i| lambda {|x| x.object_id } } }
  bm.report("block:   loop 10,000,000 times       ") { (1..10_000_000).each {|i| i.object_id } }
end

Benchmark.bm do |bm|
  bm.report("to_proc: gen 10,000,000 times        ") { (1..10_000_000).each {|i| :object_id.to_proc } }
  bm.report("to_proc: loop 10,000,000 times       ") { (1..10_000_000).each(&:object_id) }
end

class Symbol
  def to_proc
    lambda {|x| x.send(self) }
  end
end

Benchmark.bm do |bm|
  bm.report("to_proc (send): gen 10,000,000 times ") { (1..10_000_000).each {|i| :object_id.to_proc } }
  bm.report("to_proc (send): loop 10,000,000 times") { (1..10_000_000).each(&:object_id) }
end

class Symbol
  def to_proc
    eval("lambda {|x| x.#{self} }")
  end
end

Benchmark.bm do |bm|
  bm.report("to_proc (eval): gen 10,000,000 times ") { (1..10_000_000).each {|i| :object_id.to_proc } }
  bm.report("to_proc (eval): loop 10,000,000 times") { (1..10_000_000).each(&:object_id) }
end

class Symbol
  @@memoized_procs = {}
  def to_proc
    @@memoized_procs[self] ||= eval("lambda {|x| x.#{self} }")
  end
end

Benchmark.bm do |bm|
  bm.report("to_proc (memo): gen 10,000,000 times ") { (1..10_000_000).each {|i| :object_id.to_proc } }
  bm.report("to_proc (memo): loop 10,000,000 times") { (1..10_000_000).each(&:object_id) }
end
