Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add comparison from this article #43

Open
gogainda opened this issue Jul 10, 2015 · 2 comments
Open

Add comparison from this article #43

gogainda opened this issue Jul 10, 2015 · 2 comments
Labels

Comments

@gogainda
Copy link

http://blog.honeybadger.io/how-openstruct-and-hashes-can-kill-performance

@KostiantynPopovych
Copy link
Contributor

Hey @gogainda, if you are still interested in this, can you add it please, if you don't mind?

@gogainda
Copy link
Author

gogainda commented Oct 1, 2022

Hi, sorry, dont have capacity for that right now. Pasting here code which should be adopted for fast-ruby project:

require 'benchmark/ips'
require 'ostruct'


# Enable and start GC before each job run. Disable GC afterwards.
#
# Inspired by https://www.omniref.com/ruby/2.2.1/symbols/Benchmark/bm?#annotation=4095926&line=182
class GCSuite
  def warming(*)
    run_gc
  end

  def running(*)
    run_gc
  end

  def warmup_stats(*)
  end

  def add_report(*)
  end

  private

  def run_gc
    GC.enable
    GC.start
    GC.disable
  end
end

suite = GCSuite.new


data = { x: 100, y: 200 }


PointStruct = Struct.new(:x, :y)

class FakedPointStruct
  attr_accessor :x, :y
  def initialize(x, y)
    @x = x
    @y = y
  end
end

class PointClass
  attr_accessor :x, :y
  def initialize(args)
    @x = args.fetch(:x) # NOTE: Hash#fetch -> performance impact
    @y = args.fetch(:y)
  end
end


puts "\n\nINITIALIZATION =========="

Benchmark.ips do |x|
  x.config(suite: suite)

  # Create Objects as a reference value
  x.report("Object.new") { Object.new }

  x.report("FakedPointStruct") { FakedPointStruct.new(100, 200) }
  x.report("PointStruct") { PointStruct.new(100, 200) }
  x.report("Hash[]") { Hash[data] }
  x.report("PointClass") { PointClass.new(data) }
  x.report("Hash#merge") { Hash.new.merge(data) }
  x.report("OpenStruct") { OpenStruct.new(data) }
end

puts "\n\nREAD =========="

point_struct = PointStruct.new(100, 200)
point_class = PointClass.new(data)
point_hash = Hash[data]
point_open_struct = OpenStruct.new(data)

Benchmark.ips do |x|
  x.config(suite: suite)

  x.report("PointStruct") { point_struct.x }
  x.report("PointClass") {  point_class.x }
  x.report("Hash#fetch") { point_hash.fetch(:x) }
  x.report("Hash#[]") { point_hash[:x] }
  x.report("OpenStruct") {  point_open_struct.x }
end


puts "\n\nWRITE =========="

Benchmark.ips do |x|
  x.config(suite: suite)

  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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants