Skip to content

Instantly share code, notes, and snippets.

@adamstrickland
Last active April 6, 2020 19:55
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 adamstrickland/c99441c6c5522789d350bd5ddf75fd5e to your computer and use it in GitHub Desktop.
Save adamstrickland/c99441c6c5522789d350bd5ddf75fd5e to your computer and use it in GitHub Desktop.
require "securerandom"
require "benchmark"
require "google_hash"
require "memory_profiler"
require "pry"
class Item
def initialize
@keep = ([0, 1].sample == 1)
@key = SecureRandom.uuid
end
attr_reader :key
def keep?
@keep
end
end
mutable_hash_impl = ->(items) {
some_hash = Hash.new
items.each do |item|
next if item.keep?
some_hash[item.key] = item
end
some_hash
}
pipeline_impl = ->(items) {
items.select do |item|
!item.keep?
end.map do |item|
[item.key, item]
end.to_h
}
reduce_impl = ->(items) {
items.reduce(Hash.new) do |hash, item|
hash[item.key] = item unless item.keep?
hash
end
}
ghash_dense_impl = ->(items) {
some_hash = GoogleHashDenseRubyToRuby.new
items.each do |item|
next if item.keep?
some_hash[item.key] = item
end
some_hash
}
ghash_sparse_impl = ->(items) {
some_hash = GoogleHashSparseRubyToRuby.new
items.each do |item|
next if item.keep?
some_hash[item.key] = item
end
some_hash
}
tests = [
["mutable hash ", mutable_hash_impl],
["select + map ", pipeline_impl],
["reduce ", reduce_impl],
["g-hash dense ", ghash_dense_impl],
["g-hash sparse", ghash_sparse_impl],
]
shuffled_tests = tests.shuffle
control_items = 10.times.map{ Item.new }
control = mutable_hash_impl.call(control_items)
controls = tests.map do |name, impl|
test = impl.call(control_items)
if control.keys.sort == test.keys.sort
if control.keys.all?{ |k| control[k] == test[k] }
nil
else
"#{name.strip}: (values)"
end
else
"#{name.strip}: (keys)"
end
end.compact
raise "FAIL! #{controls.join(', ')} did not match" unless controls.empty?
# size = 1_000_000
size = 500_000
# size = 100_000
# size = 10_000
items = size.times.map{ Item.new }
Benchmark.bmbm do |bm|
shuffled_tests.each do |name, impl|
bm.report(name) do
impl.call(items)
end
end
end
puts
puts
puts '*' * 80
puts
puts
mp_rp_options = {
top: 10,
allow_files: File.expand_path(__FILE__),
}
mp_pp_options = {
color_output: true,
retained_strings: 0,
allocated_strings: 0,
detailed_report: false,
scale_bytes: true,
normalize_paths: true,
}
shuffled_tests.each do |name, impl|
puts name
MemoryProfiler.report(mp_rp_options) do
impl.call(items)
end.pretty_print(mp_pp_options)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment