require 'memory_profiler'
require 'benchmark'

N = 100
def test_lazy(array)
  Benchmark.bm(10) do |r|
    l = r.report('Lazy:') do
      N.times do
        array.lazy.map { |x| x * 10 }.map { |x| x * 100 }.map { |x| x * 100 }.each { |x| x * 1000 }
      end
    end
    s = r.report('Normal:') do
      N.times do
        array.map { |x| x * 10 }.map { |x| x * 100 }.map { |x| x * 100 }.each { |x| x * 1000 }
      end
    end
    [l / s]
  end
end
def test_memory(name, arr)
  puts "+"*50
  puts name
  report = MemoryProfiler.report do
    arr.map { |x| x * 10 }.map { |x| x * 100 }.map { |x| x * 100 }.each { |x| x * 1000 }
  end

  puts "Total allocated: #{report.total_allocated_memsize} bytes (#{report.total_allocated} objects)"
  puts "Total retained:  #{report.total_retained_memsize} bytes (#{report.total_retained} objects)"
  puts

  puts "allocated memory by class"
  puts "-"*50
  report.allocated_memory_by_class.each do |item|
    puts "#{item[:count].to_s.rjust(10)}  #{item[:data]}"
  end
  puts
  puts "allocated objects by class"
  puts "-"*50
  report.allocated_objects_by_class.each do |item|
    puts "#{item[:count].to_s.rjust(10)}  #{item[:data]}"
  end
  puts "+"*50
end

arr = [1,2,3]*1000
test_lazy(arr)
test_memory('Lazy:', arr.lazy)
test_memory('Normal:', arr)


