Last active
August 29, 2015 14:01
-
-
Save mfpiccolo/797cc8849df4b3b4f55f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "json" | |
require 'benchmark' | |
require 'bigdecimal/math' | |
class Hash | |
def to_struct | |
k = self.keys | |
klass = k.map(&:to_s).sort_by {|word| word.downcase}.join.capitalize | |
begin | |
Kernel.const_get("Struct::" + klass).new(*self.values_at(*k)) | |
rescue NameError | |
Struct.new(klass, *(k)).new(*self.values_at(*k)) | |
end | |
end | |
end | |
# You have a hash that you have built in your app | |
sample_hash = { | |
foo_key: "foo_val", | |
bar_key: "bar_val", | |
baz_key: "baz_val", | |
foo1_key: "foo_val", | |
bar1_key: "bar_val", | |
baz1_key: "baz_val", | |
foo2_key: "foo_val", | |
bar2_key: "bar_val", | |
baz2_key: "baz_val", | |
foo3_key: "foo_val", | |
bar3_key: "bar_val", | |
baz3_key: "baz_val", | |
foo4_key: "foo_val", | |
bar4_key: "bar_val", | |
baz4_key: "baz_val", | |
foo5_key: "foo_val", | |
bar5_key: "bar_val", | |
baz5_key: "baz_val", | |
foo6_key: "foo_val", | |
bar6_key: "bar_val", | |
baz6_key: "baz_val", | |
foo7_key: "foo_val", | |
bar7_key: "bar_val", | |
baz7_key: "baz_val", | |
} | |
# Then you have JSON coming from some external api | |
json_response = "{\"qux_key\":\"qux_val\",\"quux_key\":\"quux_val\",\"corge_key\":\"corge_val\"}" | |
hash_with_unknown_keys = JSON.parse(json_response) | |
# Merge these two together | |
sample_hash.merge!(hash_with_unknown_keys) | |
iterations = 100_000 | |
Benchmark.bm do |bm| | |
bm.report "#to_struct" do | |
iterations.times do | |
# Would be super nice if I could convert this to a struct with a method | |
# Somehow a bit faster than the explicit example below and much faster than open struct | |
sample_struct = sample_hash.to_struct | |
unless sample_struct.foo_key == "foo_val" | |
raise "Wrong value" | |
end | |
end | |
end | |
bm.report "Struct" do | |
iterations.times do | |
sample_struct = Struct.new(*sample_hash.keys) | |
.new(*sample_hash.values) | |
unless sample_struct.foo_key == "foo_val" | |
raise "Wrong value" | |
end | |
end | |
end | |
bm.report "OpenStruct" do | |
iterations.times do | |
sample_open_struct = OpenStruct.new(sample_hash) | |
unless sample_open_struct.foo_key == "foo_val" | |
raise "Wrong value" | |
end | |
end | |
end | |
end | |
# user system total real | |
# #to_struct 4.030000 0.010000 4.040000 ( 4.072031) | |
# Struct 6.870000 0.290000 7.160000 ( 7.320459) | |
# OpenStruct 23.550000 0.210000 23.760000 ( 23.895187) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment