Skip to content
This repository has been archived by the owner on Oct 6, 2019. It is now read-only.

Add benchmarks #25

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ end
group :tools do
gem 'rubocop', '~> 0.31'

gem 'faker'
gem 'guard'
gem 'guard-rspec'
gem 'guard-rubocop'
Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ Resources:
- [Guides](http://rom-rb.org/guides/basics/mappers/)
- [Importing Data with ROM and Transproc](http://solnic.eu/2015/07/15/importing-data-with-rom-and-transproc.html)

Contributing

[Fork it](https://github.com/rom-rb/rom-mapper/fork)
Create your feature branch (`git checkout -b my-new-feature`)
Run the benchmark suite (`bin/benchmarks`)
Commit your changes (`git commit -am 'Add some feature'`)
Run the benchmark suite again for comparison (`bin/benchmarks`)
Push to the branch (`git push origin my-new-feature`)
Create a new Pull Request

## License

See `LICENSE` file.
See [LICENSE](blob/master/LICENSE) file.
23 changes: 23 additions & 0 deletions benchmarks/model_instantiation
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env ruby
# encoding: utf-8

require_relative 'utils/setup.rb'

user_model = Class.new(OpenStruct)

mapper = build_mapper do
attribute :name
attribute :email
model user_model
end

tuples = create_tuple_collection(100) do
{
name: Faker::Name.name,
email: Faker::Internet.email
}
end

run('model_instantiation') do |x|
x.report { mapper.call(tuples) }
end
20 changes: 20 additions & 0 deletions benchmarks/noop
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env ruby
# encoding: utf-8

require_relative 'utils/setup.rb'

mapper = build_mapper do
attribute :name
attribute :email
end

tuples = create_tuple_collection(100) do
{
name: Faker::Name.name,
email: Faker::Internet.email
}
end

run('noop') do |x|
x.report { mapper.call(tuples) }
end
22 changes: 22 additions & 0 deletions benchmarks/reject_keys
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env ruby
# encoding: utf-8

require_relative 'utils/setup.rb'

mapper = build_mapper do
reject_keys true
attribute :name
attribute :email
end

tuples = create_tuple_collection(100) do
{
name: Faker::Name.name,
email: Faker::Internet.email,
Faker::Lorem.word => Faker::Lorem.word
}
end

run('reject_keys') do |x|
x.report { mapper.call(tuples) }
end
20 changes: 20 additions & 0 deletions benchmarks/rename_keys
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env ruby
# encoding: utf-8

require_relative 'utils/setup.rb'

mapper = build_mapper do
attribute :name, from: 'name'
attribute :email, from: 'email'
end

tuples = create_tuple_collection(100) do
{
'name' => Faker::Name.name,
'email' => Faker::Internet.email
}
end

run('rename_keys') do |x|
x.report { mapper.call(tuples) }
end
10 changes: 10 additions & 0 deletions benchmarks/results/model_instantiation
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
=> benchmark: model_instantiation
=> host: andy-HP-ENVY-TS-15-Notebook-PC
=> revision: b7df14f0aacb67d1e006bf1795e0ca45481bc925
=> repo_state: clean

Calculating -------------------------------------
167.000 i/100ms
-------------------------------------------------
1.612k (±10.0%) i/s - 8.016k
********************************************************************************
10 changes: 10 additions & 0 deletions benchmarks/results/noop
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
=> benchmark: noop
=> host: andy-HP-ENVY-TS-15-Notebook-PC
=> revision: b7df14f0aacb67d1e006bf1795e0ca45481bc925
=> repo_state: clean

Calculating -------------------------------------
90.342k i/100ms
-------------------------------------------------
1.497M (± 4.5%) i/s - 7.498M
********************************************************************************
10 changes: 10 additions & 0 deletions benchmarks/results/reject_keys
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
=> benchmark: reject_keys
=> host: andy-HP-ENVY-TS-15-Notebook-PC
=> revision: b7df14f0aacb67d1e006bf1795e0ca45481bc925
=> repo_state: clean

Calculating -------------------------------------
492.000 i/100ms
-------------------------------------------------
4.925k (± 6.8%) i/s - 24.600k
********************************************************************************
10 changes: 10 additions & 0 deletions benchmarks/results/rename_keys
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
=> benchmark: rename_keys
=> host: andy-HP-ENVY-TS-15-Notebook-PC
=> revision: b7df14f0aacb67d1e006bf1795e0ca45481bc925
=> repo_state: clean

Calculating -------------------------------------
889.000 i/100ms
-------------------------------------------------
9.028k (± 3.9%) i/s - 45.339k
********************************************************************************
10 changes: 10 additions & 0 deletions benchmarks/results/symbolize_keys
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
=> benchmark: symbolize_keys
=> host: andy-HP-ENVY-TS-15-Notebook-PC
=> revision: b7df14f0aacb67d1e006bf1795e0ca45481bc925
=> repo_state: clean

Calculating -------------------------------------
899.000 i/100ms
-------------------------------------------------
9.164k (± 3.8%) i/s - 45.849k
********************************************************************************
21 changes: 21 additions & 0 deletions benchmarks/symbolize_keys
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env ruby
# encoding: utf-8

require_relative 'utils/setup.rb'

mapper = build_mapper do
symbolize_keys true
attribute :name
attribute :email
end

tuples = create_tuple_collection(100) do
{
'name' => Faker::Name.name,
'email' => Faker::Internet.email
}
end

run('symbolize_keys') do |x|
x.report { mapper.call(tuples) }
end
84 changes: 84 additions & 0 deletions benchmarks/utils/setup.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
require 'bundler'
Bundler.require

require 'socket'
require 'ostruct'
require 'benchmark/ips'
require 'faker'
require 'rom-mapper'

begin
require 'byebug'
rescue LoadError
end

# 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

def hr
puts "*" * 80
end

def run(title, &block)
benchmark(title, &block)
end

def git_state
state = `git status -uno --porcelain`.split($/).reject do |line|
line.split(' ').last.start_with?('benchmarks/results/')
end

state.empty? ? 'clean' : "#{$/} => #{state.join("#{$/} => ")}"
end

def benchmark(title)
puts "=> benchmark: #{title}"
puts "=> host: #{Socket.gethostname}"
puts "=> revision: #{`git rev-parse HEAD`}"
puts "=> repo_state: #{git_state}"
puts $/
Benchmark.ips do |x|
x.config(suite: GCSuite.new)
yield x
x.compare!
end
hr
end

def create_mapper(&block)
Class.new(ROM::Mapper).tap do |mapper_klass|
mapper_klass.instance_eval(&block)
end
end

def build_mapper(&block)
create_mapper(&block).build
end

def create_tuple_collection(size, &block)
size.times.map { block.call }
end
11 changes: 11 additions & 0 deletions bin/benchmark
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env ruby
# encoding: utf-8

BENCHMARK_DIR = File.expand_path('../../benchmarks', __FILE__)
RESULTS_DIR = File.expand_path('../../benchmarks/results', __FILE__)
BENCHMARKS = Dir[File.join(BENCHMARK_DIR, '*')].select {|f| File.file?(f) }.sort
RESULTS = BENCHMARKS.map { |bm| File.join(RESULTS_DIR, File.basename(bm)) }

BENCHMARKS.zip(RESULTS).each do |benchmark, result|
system("#{benchmark} | tee #{result}")
end