Skip to content

Instantly share code, notes, and snippets.

@rmosolgo
Created February 20, 2017 01:50
Show Gist options
  • Select an option

  • Save rmosolgo/3a2876dbbb721749176644da7325827e to your computer and use it in GitHub Desktop.

Select an option

Save rmosolgo/3a2876dbbb721749176644da7325827e to your computer and use it in GitHub Desktop.
Compare creation & access times for key-value storage in Ruby (Class, Struct, OpenStruct, Hash)
~/code/graphql $ ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin14]
~/code/graphql $ ruby struct_bench.rb
========================================
Create and Access
========================================
Warming up --------------------------------------
Hash#[] 118.707k i/100ms
Hash#fetch 113.228k i/100ms
Struct 195.640k i/100ms
OpenStruct 9.301k i/100ms
Class 64.503k i/100ms
Calculating -------------------------------------
Hash#[] 1.697M (± 4.8%) i/s - 8.547M in 5.049520s
Hash#fetch 1.571M (± 7.7%) i/s - 7.813M in 5.012878s
Struct 3.936M (± 4.0%) i/s - 19.760M in 5.028583s
OpenStruct 98.347k (± 2.9%) i/s - 492.953k in 5.016646s
Class 767.913k (± 4.0%) i/s - 3.870M in 5.048166s
Comparison:
Struct: 3936003.4 i/s
Hash#[]: 1696710.9 i/s - 2.32x slower
Hash#fetch: 1570913.6 i/s - 2.51x slower
Class: 767912.6 i/s - 5.13x slower
OpenStruct: 98347.4 i/s - 40.02x slower
========================================
Create
========================================
Warming up --------------------------------------
Hash 125.138k i/100ms
Struct 212.084k i/100ms
OpenStruct 57.104k i/100ms
Class 64.532k i/100ms
Calculating -------------------------------------
Hash 1.859M (± 4.0%) i/s - 9.385M in 5.057965s
Struct 4.707M (± 3.9%) i/s - 23.541M in 5.009567s
OpenStruct 693.644k (± 3.5%) i/s - 3.483M in 5.027858s
Class 787.318k (± 5.9%) i/s - 3.936M in 5.019975s
Comparison:
Struct: 4706838.4 i/s
Hash: 1858592.0 i/s - 2.53x slower
Class: 787317.8 i/s - 5.98x slower
OpenStruct: 693644.2 i/s - 6.79x slower
========================================
Access
========================================
Warming up --------------------------------------
Hash#[] 284.267k i/100ms
Hash#fetch 262.122k i/100ms
Struct 282.285k i/100ms
OpenStruct 205.608k i/100ms
Class 293.014k i/100ms
Calculating -------------------------------------
Hash#[] 8.841M (± 7.8%) i/s - 43.777M in 5.004526s
Hash#fetch 6.977M (± 5.0%) i/s - 34.862M in 5.009896s
Struct 8.774M (± 4.3%) i/s - 44.036M in 5.028365s
OpenStruct 4.297M (± 3.5%) i/s - 21.589M in 5.030635s
Class 9.553M (± 5.9%) i/s - 47.761M in 5.017911s
Comparison:
Class: 9553056.9 i/s
Hash#[]: 8840715.6 i/s - same-ish: difference falls within error
Struct: 8774498.7 i/s - same-ish: difference falls within error
Hash#fetch: 6976943.2 i/s - 1.37x slower
OpenStruct: 4296913.4 i/s - 2.22x slower
~/code/graphql $ ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin14]
~/code/graphql $ ruby struct_bench.rb
========================================
Create and Access
========================================
Warming up --------------------------------------
Hash#[] 122.120k i/100ms
Hash#fetch 115.835k i/100ms
Struct 207.760k i/100ms
OpenStruct 9.396k i/100ms
Class 66.262k i/100ms
Calculating -------------------------------------
Hash#[] 1.678M (± 5.8%) i/s - 8.426M in 5.043414s
Hash#fetch 1.576M (± 4.6%) i/s - 7.877M in 5.008378s
Struct 3.889M (± 4.5%) i/s - 19.529M in 5.033137s
OpenStruct 94.218k (± 5.9%) i/s - 479.196k in 5.107142s
Class 777.378k (± 5.9%) i/s - 3.909M in 5.049937s
Comparison:
Struct: 3888560.4 i/s
Hash#[]: 1677979.1 i/s - 2.32x slower
Hash#fetch: 1576180.1 i/s - 2.47x slower
Class: 777377.5 i/s - 5.00x slower
OpenStruct: 94218.0 i/s - 41.27x slower
========================================
Create
========================================
Warming up --------------------------------------
Hash 128.600k i/100ms
Struct 224.722k i/100ms
OpenStruct 61.213k i/100ms
Class 67.290k i/100ms
Calculating -------------------------------------
Hash 1.826M (± 4.6%) i/s - 9.131M in 5.011098s
Struct 4.573M (± 4.3%) i/s - 22.922M in 5.022855s
OpenStruct 698.906k (± 3.6%) i/s - 3.550M in 5.086783s
Class 803.859k (± 3.4%) i/s - 4.037M in 5.028593s
Comparison:
Struct: 4572506.9 i/s
Hash: 1826051.2 i/s - 2.50x slower
Class: 803858.8 i/s - 5.69x slower
OpenStruct: 698905.9 i/s - 6.54x slower
========================================
Access
========================================
Warming up --------------------------------------
Hash#[] 298.373k i/100ms
Hash#fetch 268.598k i/100ms
Struct 298.924k i/100ms
OpenStruct 197.961k i/100ms
Class 306.494k i/100ms
Calculating -------------------------------------
Hash#[] 8.319M (± 6.9%) i/s - 41.474M in 5.019781s
Hash#fetch 6.148M (± 5.3%) i/s - 30.889M in 5.039206s
Struct 8.074M (±10.6%) i/s - 39.757M in 5.007988s
OpenStruct 3.918M (± 7.1%) i/s - 19.598M in 5.035454s
Class 9.394M (± 5.4%) i/s - 46.894M in 5.007424s
Comparison:
Class: 9394405.5 i/s
Hash#[]: 8318559.1 i/s - same-ish: difference falls within error
Struct: 8074174.5 i/s - same-ish: difference falls within error
Hash#fetch: 6148417.9 i/s - 1.53x slower
OpenStruct: 3918462.1 i/s - 2.40x slower
require "ostruct"
require "benchmark/ips"
PointSt = Struct.new(:lat, :lon)
class PointObj
def initialize(lat:, lon:)
@lat = lat
@lon = lon
end
attr_reader :lat, :lon
end
header = "==" * 20
puts header
puts "Create and Access"
puts header
Benchmark.ips do |bm|
bm.report("Hash") {
pt = { lat: 100, lon: 50 }
pt[:lat]
pt[:lon]
}
bm.report("Struct") {
pt = PointSt.new(100, 50)
pt.lat
pt.lon
}
bm.report("OpenStruct") {
pt = OpenStruct.new(lat: 100, lon: 50)
pt.lat
pt.lon
}
bm.report("Class") {
pt = PointObj.new(lat: 50, lon: 100)
pt.lat
pt.lon
}
bm.compare!
end
puts header
puts "Create"
puts header
Benchmark.ips do |bm|
bm.report("Hash") {
{ lat: 100, lon: 50 }
}
bm.report("Struct") {
PointSt.new(100, 50)
}
bm.report("OpenStruct") {
OpenStruct.new(lat: 100, lon: 50)
}
bm.report("Class") {
PointObj.new(lat: 50, lon: 100)
}
bm.compare!
end
puts header
puts "Access"
puts header
PT_HASH = { lat: 100, lon: 50 }
PT_ST = PointSt.new(100, 50)
PT_OS = OpenStruct.new(lat: 100, lon: 50)
PT_C = PointObj.new(lat: 50, lon: 100)
Benchmark.ips do |bm|
bm.report("Hash") {
PT_HASH[:lat]
PT_HASH[:lon]
}
bm.report("Struct") {
PT_ST.lat
PT_ST.lon
}
bm.report("OpenStruct") {
PT_OS.lat
PT_OS.lon
}
bm.report("Class") {
PT_C.lat
PT_C.lon
}
bm.compare!
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment