Skip to content

Instantly share code, notes, and snippets.

@skipkayhil
Last active August 15, 2022 16:22
Show Gist options
  • Save skipkayhil/0bbee9df5e2a57bc13ece4a9db353b5f to your computer and use it in GitHub Desktop.
Save skipkayhil/0bbee9df5e2a57bc13ece4a9db353b5f to your computer and use it in GitHub Desktop.
Benchmark for rails/rails#45035
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "rails", github: "rails/rails", branch: "main"
gem "sqlite3"
gem "benchmark-ips"
end
require 'active_record'
require 'logger'
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :posts, force: true do |t|
t.string :author
t.string :title
end
create_table :each_posts, force: true do |t|
t.string :author
t.string :title
end
end
class Post < ActiveRecord::Base
def deconstruct_keys(keys)
keys.each_with_object({}) do |key, deconstructed|
string_key = key.to_s
deconstructed[key] = _read_attribute(string_key) if attribute_method?(string_key)
end
end
end
class EachPost < ActiveRecord::Base
def deconstruct_keys(keys)
deconstructed = {}
keys.each do |key|
string_key = key.to_s
deconstructed[key] = _read_attribute(string_key) if attribute_method?(string_key)
end
deconstructed
end
end
def match_model(model)
case model
in { author: 'John' }
true
else
false
end
end
p1object = Post.new(author: 'John', title: 'Rails!')
p1each = EachPost.new(author: 'John', title: 'Rails!')
p2object = Post.new(author: 'Jane', title: 'Ruby!')
p2each = EachPost.new(author: 'Jane', title: 'Ruby!')
[p1object, p1each].each do |m|
raise m.inspect unless match_model(m)
end
[p2object, p2each].each do |m|
raise m.inspect if match_model(m)
end
Benchmark.ips do |x|
x.report("each_with_object") { match_model(p1object) }
x.report("each") { match_model(p1each) }
x.compare!
end
Benchmark.ips do |x|
x.report("each_with_object") { match_model(p2object) }
x.report("each") { match_model(p2each) }
x.compare!
end
Warming up --------------------------------------
each_with_object 95.004k i/100ms
each 107.935k i/100ms
Calculating -------------------------------------
each_with_object 959.392k (± 1.3%) i/s - 4.845M in 5.051211s
each 1.063M (± 1.7%) i/s - 5.397M in 5.076504s
Comparison:
each: 1063385.6 i/s
each_with_object: 959391.7 i/s - 1.11x (± 0.00) slower
Warming up --------------------------------------
each_with_object 92.591k i/100ms
each 105.836k i/100ms
Calculating -------------------------------------
each_with_object 952.555k (± 2.0%) i/s - 4.815M in 5.056662s
each 1.069M (± 1.9%) i/s - 5.398M in 5.048931s
Comparison:
each: 1069442.7 i/s
each_with_object: 952555.0 i/s - 1.12x (± 0.00) slower
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment