Use #flat_map { ... } instead of #map { ... }.flatten by britishtea
#ruby's #flat_map is much faster than combining #map and #flatten.
require 'benchmark'
arr = 1_000.times.map { (1..100).to_a }
Benchmark.bm 10 do |x|
x.report('#flatten') { arr.map { |x| x << 1001 }.flatten(1) }
x.report('#flat_map') { arr.flat_map { |x| x << 1001 } }
end
The results
# $ ruby flat_map.rb
# user system total real
# #flatten 0.010000 0.000000 0.010000 ( 0.024426)
# #flat_map 0.000000 0.000000 0.000000 ( 0.001466)
# $ ruby flat_map.rb
# user system total real
# #flatten 0.010000 0.000000 0.010000 ( 0.031431)
# #flat_map 0.010000 0.000000 0.010000 ( 0.001546)
Comments
cvb commented 5 months ago
you should try to compare with flatten!, it should be faster
kritik commented 5 months ago
Seems that flat_map still to be faster
britishtea commented 5 months ago
These are all valid points.
Doesn't
[[1,2],3].flat_map.to_areturn[[1, 2], 3]because#flat_mapwithout a block returns an Enumerator, though?Note that my benchmarks used
#flatten(1)instead of simply#flatten, to ensure equal output.I updated my benchmarks, keeping your comments in mind. I included a map-reduce test, based on your comment.
releu commented 5 months ago
Cool. Thanks!
makaroni4 commented 5 months ago
@britishtea thx, great tip!
makaroni4 commented 5 months ago
And I immediately found a great use for flat_map method:
http://gistflow.com/posts/582-array-include-vs-hash-has_key
Also @britishtea take a look at benchmark/ips, it makes more scientific benchmarks:
http://gistflow.com/posts/136-benchmarking-with-ruby