A presentation at ParisRB Meetup in in Paris, France by Sunny Ripert
Ruby Benchmark Ne faites pas con ance à votre instinct
Problématique hash = 42 => 43 => 44 => # … } { { min: 5, max: 10 }, { min: 4, max: 9 }, { min: 3, max: 7 }, Je souhaite faire la somme des min.
Solutions require ‘active_support/core_ext/enumerable’ hash = 42 => 43 => 44 => } { { min: 5, max: 10 }, { min: 4, max: 9 }, { min: 3, max: 7 }, hash.values.inject(0) { |inc, h| inc + h[:min] } hash.sum { |_, h| h[:min] }
Benchmark ! require ‘benchmark’ Benchmark.bm do |x| x.report { 500.times { … } } x.report { 500.times { … } } end
Quelle est la solution la plus performante ? each_inject: hash.each_value.inject(0) { |i, h| i + h[:min] } each_map_reduce: hash.each_value.map { |h| h[:min] }.reduce(:+) each_sum: hash.each_value.sum { |v| v[:min] } inject: hash.inject(0) { |i, h| i + h[1][:min] } inject_block_var: hash.inject(0) { |i, (, v)| i + v[:min] } sum_block_var: hash.sum { |, v| v[:min] } values_inject: hash.values.inject(0) { |i, h| i + h[:min] } values_map_reduce: hash.values.map { |h| h[:min] }.reduce(:+) values_sum: { |v| v[:min] } hash.values.sum
Benchmark ! require ‘bmark’ # https://gist.github.com/sunny/c47982974f749da82b6f require ‘active_support/core_ext/enumerable’ hash = {} 100.times do |i| hash[i] = { min: 5, max: 10 } end bmark 200_000, each_inject: each_map_reduce: each_sum: inject: inject_block_var: sum_block_var: values_inject: values_map_reduce: values_sum: -> -> -> -> -> -> -> -> -> { { { { { { { { { hash.each_value.inject(0) hash.each_value.map hash.each_value.sum hash.inject(0) hash.inject(0) hash.sum hash.values.inject(0) hash.values.map hash.values.sum { { { { { { { { { |i, |h| |v| |i, |i, |, |i, |h| |v| h| i + h[:min] } }, h[:min] }.reduce(:+) }, v[:min] } }, h| i + h[1][:min] } }, (, v)| i + v[:min] } }, v| v[:min] } }, h| i + h[:min] } }, h[:min] }.reduce(:+) }, v[:min] } }
Roulements de tambours…
Résultats each_inject each_map_reduce each_sum inject inject_block_var sum_block_var values_inject values_map_reduce values_sum user 2.850000 4.290000 5.120000 4.020000 4.210000 6.260000 2.290000 3.170000 3.960000 system 0.000000 0.000000 0.010000 0.000000 0.010000 0.000000 0.010000 0.010000 0.010000 total 2.850000 4.290000 5.130000 4.020000 4.220000 6.260000 2.300000 3.180000 3.970000 ( ( ( ( ( ( ( ( ( real 2.858093) 4.296114) 5.126060) 4.031549) 4.213347) 6.263503) 2.296429) 3.188121) 3.966809)
Résultats each_inject: each_map_reduce: each_sum: inject: inject_block_var: sum_block_var: values_inject: values_map_reduce: values_sum: hash.each_value.inject(0) hash.each_value.map hash.each_value.sum hash.inject(0) hash.inject(0) hash.sum hash.values.inject(0) hash.values.map hash.values.sum { { { { { { { { { |i, |h| |v| |i, |i, |, |i, |h| |v| h| i + h[:min] } h[:min] }.reduce(:+) v[:min] } h| i + h[1][:min] } (, v)| i + v[:min] } v| v[:min] } h| i + h[:min] } h[:min] }.reduce(:+) v[:min] }
2.86 4.23 5.13 4.03 4.21 6.26 2.30 3.19 3.97
Merci !