# frozen_string_literal: true require "bundler" Bundler.require require "ostruct" data = { x: 100, y: 200, z: "some other data", a: "more text data", b: 1100.00, c: Time.now } PointStruct = Struct.new(:x, :y, :z, :a, :b, :c) class PointClass attr_accessor :x, :y, :z, :a, :b, :c def initialize(args) @x = args.fetch(:x) @y = args.fetch(:y) @z = args.fetch(:z) @a = args.fetch(:a) @b = args.fetch(:b) @c = args.fetch(:c) end end puts "\n\nINITIALIZATION ==========" Benchmark.ips do |x| x.report("OpenStruct") { OpenStruct.new(data) } x.report("Struct") { PointStruct.new(data) } x.report("Class") { PointClass.new(data) } x.report("Hash") { {}.merge(data) } x.compare! 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("OpenStruct") { point_open_struct.z } x.report("Struct") { point_struct.z } x.report("Class") { point_class.z } x.report("Hash") { point_hash.fetch(:z) } x.compare! end puts "\n\nWRITE ==========" Benchmark.ips do |x| x.report("OpenStruct") do point_open_struct.x = "even more data" point_open_struct.z = 1000.00 point_open_struct.b = 100 end x.report("Struct") do point_struct.x = "even more data" point_struct.z = 1000.00 point_struct.b = 100 end x.report("Class") do point_class.x = "even more data" point_class.z = 1000.00 point_class.b = 100 end x.report("Hash") do point_hash[:x] = "even more data" point_hash[:z] = 1000.00 point_hash[:b] = 100 end x.compare! end puts "\n\n############# MEMORY ==========" puts "\n\nINITIALIZATION ==========" Benchmark.memory do |x| x.report("OpenStruct") { OpenStruct.new(data) } x.report("Struct") { PointStruct.new(data) } x.report("Class") { PointClass.new(data) } x.report("Hash") { {}.merge(data) } x.compare! end