Skip to content

Instantly share code, notes, and snippets.

@palkan
Last active December 4, 2019 09:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save palkan/900767d6ac7c648f5f788e62394973e1 to your computer and use it in GitHub Desktop.
Save palkan/900767d6ac7c648f5f788e62394973e1 to your computer and use it in GitHub Desktop.
many vs flat_map bench
# See:
# - https://codon.com/refactoring-ruby-with-monads#multiple-results
# - Rails PR: https://github.com/rails/rails/issues/37875
require "benchmark_driver"
Benchmark.driver do |x|
x.prelude %Q{
Blog = Struct.new(:categories)
Category = Struct.new(:posts)
Post = Struct.new(:comments)
blogs = [
Blog.new([
Category.new([
Post.new(['I love cats', 'I love dogs']),
Post.new(['I love mice', 'I love pigs'])
]),
Category.new([
Post.new(['I hate cats', 'I hate dogs']),
Post.new(['I hate mice', 'I hate pigs'])
])
]),
Blog.new([
Category.new([
Post.new(['Red is better than blue'])
]),
Category.new([
Post.new(['Blue is better than red'])
])
])
]
Many = Struct.new(:values) do
def and_then(&block)
Many.new(values.map(&block).flat_map(&:values))
end
def method_missing(*args, &block)
and_then do |value|
Many.new(value.public_send(*args, &block))
end
end
end
}
x.report "flat_map", %{ blogs.flat_map(&:categories).flat_map(&:posts).flat_map(&:comments) }
x.report "many", %{ Many.new(blogs).categories.posts.comments.values }
end
__END__
Warming up --------------------------------------
flat_map 904.475k i/s - 915.450k times in 1.012134s (1.11μs/i)
many 184.317k i/s - 191.160k times in 1.037126s (5.43μs/i)
Calculating -------------------------------------
flat_map 918.651k i/s - 2.713M times in 2.953708s (1.09μs/i)
many 189.590k i/s - 552.951k times in 2.916557s (5.27μs/i)
Comparison:
flat_map: 918650.5 i/s
many: 189590.3 i/s - 4.85x slower
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment