Skip to content

Instantly share code, notes, and snippets.

@mjc
Last active August 29, 2015 14:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjc/02f9cd379ca318c67fc5 to your computer and use it in GitHub Desktop.
Save mjc/02f9cd379ca318c67fc5 to your computer and use it in GitHub Desktop.
Class vs Struct vs OpenStruct

Ruby 2.2.2

INITIALIZATION ==========
Calculating -------------------------------------
         PointStruct   119.579k i/100ms
          PointClass   105.819k i/100ms
                Hash    74.289k i/100ms
          OpenStruct     9.480k i/100ms
-------------------------------------------------
         PointStruct      3.889M (± 5.4%) i/s -     19.491M
          PointClass      3.096M (± 4.3%) i/s -     15.555M
                Hash      1.221M (± 7.6%) i/s -      6.092M
          OpenStruct    105.725k (± 7.4%) i/s -    530.880k


READ ==========
Calculating -------------------------------------
         PointStruct   150.753k i/100ms
          PointClass   163.498k i/100ms
                Hash   151.864k i/100ms
          OpenStruct   129.658k i/100ms
-------------------------------------------------
         PointStruct      8.962M (± 7.4%) i/s -     44.623M
          PointClass      9.606M (± 7.7%) i/s -     47.741M
                Hash      7.929M (± 5.9%) i/s -     39.485M
          OpenStruct      5.381M (± 6.0%) i/s -     26.839M


WRITE ==========
Calculating -------------------------------------
         PointStruct   149.544k i/100ms
          PointClass   154.640k i/100ms
                Hash   152.754k i/100ms
          OpenStruct   122.162k i/100ms
-------------------------------------------------
         PointStruct      7.801M (± 7.2%) i/s -     38.881M
          PointClass      9.467M (± 7.6%) i/s -     47.165M
                Hash      7.920M (± 6.7%) i/s -     39.411M
          OpenStruct      3.799M (± 8.6%) i/s -     18.935M

JRuby 1.7.19 (indy on)

INITIALIZATION ==========
Calculating -------------------------------------
         PointStruct   260.139k i/100ms
          PointClass   252.441k i/100ms
                Hash   216.011k i/100ms
          OpenStruct    19.034k i/100ms
-------------------------------------------------
         PointStruct     10.047M (± 6.8%) i/s -     49.947M
          PointClass      8.977M (± 6.4%) i/s -     44.934M
                Hash      5.918M (± 6.5%) i/s -     29.594M
          OpenStruct    221.373k (±15.7%) i/s -      1.085M


READ ==========
Calculating -------------------------------------
         PointStruct   300.623k i/100ms
          PointClass   297.647k i/100ms
                Hash   291.018k i/100ms
          OpenStruct   229.041k i/100ms
-------------------------------------------------
         PointStruct     26.282M (± 8.5%) i/s -    130.170M
          PointClass     27.341M (± 7.5%) i/s -    135.727M
                Hash     21.464M (± 8.7%) i/s -    106.222M
          OpenStruct      8.168M (± 7.7%) i/s -     40.540M


WRITE ==========
Calculating -------------------------------------
         PointStruct   299.269k i/100ms
          PointClass   284.108k i/100ms
                Hash   287.819k i/100ms
          OpenStruct   203.869k i/100ms
-------------------------------------------------
         PointStruct     25.992M (± 8.6%) i/s -    128.985M
          PointClass     23.216M (± 8.6%) i/s -    115.064M
                Hash     18.886M (± 7.1%) i/s -     93.829M
          OpenStruct      6.042M (± 4.7%) i/s -     30.173M

JRuby 9000 (7af46ed)

INITIALIZATION ==========
Calculating -------------------------------------
         PointStruct   172.839k i/100ms
          PointClass   181.810k i/100ms
                Hash   157.846k i/100ms
          OpenStruct    14.709k i/100ms
-------------------------------------------------
         PointStruct      6.848M (± 7.2%) i/s -     34.049M
          PointClass      7.810M (± 6.4%) i/s -     38.907M
                Hash      5.304M (± 6.0%) i/s -     26.518M
          OpenStruct    165.047k (±12.0%) i/s -    823.704k


READ ==========
Calculating -------------------------------------
         PointStruct   206.341k i/100ms
          PointClass   203.604k i/100ms
                Hash   201.187k i/100ms
          OpenStruct   179.241k i/100ms
-------------------------------------------------
         PointStruct     20.308M (± 9.1%) i/s -    100.282M
          PointClass     18.446M (± 8.0%) i/s -     91.215M
                Hash     16.237M (± 9.3%) i/s -     80.274M
          OpenStruct      8.441M (± 9.7%) i/s -     41.763M


WRITE ==========
Calculating -------------------------------------
         PointStruct   209.746k i/100ms
          PointClass   203.221k i/100ms
                Hash   201.639k i/100ms
          OpenStruct   157.770k i/100ms
-------------------------------------------------
         PointStruct     19.634M (± 9.1%) i/s -     97.112M
          PointClass     18.309M (± 8.1%) i/s -     90.840M
                Hash     16.010M (± 7.6%) i/s -     79.647M
          OpenStruct      5.443M (± 5.1%) i/s -     27.294M
source 'https://rubygems.org'
gem 'benchmark-ips'
gem 'ruby-progressbar'
GEM
remote: https://rubygems.org/
specs:
benchmark-ips (2.2.0)
ruby-progressbar (1.7.5)
PLATFORMS
java
ruby
DEPENDENCIES
benchmark-ips
ruby-progressbar
BUNDLED WITH
1.10.4
require 'bundler'
Bundler.require
require 'ostruct'
data = { x: 100, y: 200 }
PointStruct = Struct.new(:x, :y)
class PointClass
attr_accessor :x, :y
def initialize(args)
@x = args.fetch(:x)
@y = args.fetch(:y)
end
end
puts "\n\nINITIALIZATION =========="
Benchmark.ips do |x|
x.config warmup: 90 if RUBY_ENGINE == 'jruby'
x.report('PointStruct') { PointStruct.new(data) }
x.report('PointClass') { PointClass.new(data) }
x.report('Hash') { {}.merge(data) }
x.report('OpenStruct') { OpenStruct.new(data) }
end
puts "\n\nREAD =========="
point_struct = PointStruct.new(data)
point_class = PointClass.new(data)
point_hash = {}.merge(data)
point_open_struct = OpenStruct.new(data)
Benchmark.ips do |x|
x.config warmup: 90 if RUBY_ENGINE == 'jruby'
x.report('PointStruct') { point_struct.x }
x.report('PointClass') { point_class.x }
x.report('Hash') { point_hash.fetch(:x) }
x.report('OpenStruct') { point_open_struct.x }
end
puts "\n\nWRITE =========="
Benchmark.ips do |x|
x.config warmup: 90 if RUBY_ENGINE == 'jruby'
x.report('PointStruct') { point_struct.x = 1 }
x.report('PointClass') { point_class.x = 1 }
x.report('Hash') { point_hash[:x] = 1 }
x.report('OpenStruct') { point_open_struct.x = 1 }
end
@starrhorne
Copy link

Hey, FYI I made a slight mistake in the code on my blog. I've fixed it and rerun the benchmarks on MRI 2.1 without any significant change.

I was initializing the PointStruct incorrectly, accidentally setting point_struct.x == {x: 100, y: 200}. The fix is to replace PointStruct.new(data) with something like PointStruct.new(100,200).

Sorry!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment