Skip to content

Commit 7f52905

Browse files
committed
Cleanup
1 parent 968aa11 commit 7f52905

File tree

4 files changed

+195
-151
lines changed

4 files changed

+195
-151
lines changed

bin/bench

Lines changed: 75 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,78 +4,98 @@ require 'benchmark'
44
require 'pathname'
55
require 'shellwords'
66

7-
ROOT = Pathname File.expand_path(['..', '..'].join(File::Separator), __FILE__)
8-
TMP_DIR = File.join(ROOT, 'tmp/bench')
7+
class Benchmarking
8+
ROOT = Pathname File.expand_path(['..', '..'].join(File::Separator), __FILE__)
9+
TMP_DIR = File.join(ROOT, 'tmp/bench')
910

10-
def temp_dir_empty?
11-
Dir[File.join(TMP_DIR, '*')].none?
12-
end
11+
attr_reader :prepend, :append
1312

14-
def empty_temp_dir
15-
FileUtils.mkdir_p(TMP_DIR)
16-
Dir[File.join(TMP_DIR, '*')].each do |file|
17-
FileUtils.rm(file)
13+
def initialize(prepend: '', append: '')
14+
@prepend = prepend
15+
@append = append
1816
end
19-
end
2017

21-
def fill_temp_dir
22-
Dir[File.join(ROOT, 'test', 'benchmark', '*.rb')].each do |file|
23-
FileUtils.cp(file, File.join(TMP_DIR, File.basename(file)))
18+
def temp_dir_empty?
19+
Dir[File.join(TMP_DIR, '*')].none?
2420
end
25-
at_exit { empty_temp_dir }
26-
end
2721

28-
def refresh_temp_dir
29-
empty_temp_dir
30-
fill_temp_dir
31-
end
22+
def empty_temp_dir
23+
FileUtils.mkdir_p(TMP_DIR)
24+
Dir[File.join(TMP_DIR, '*')].each do |file|
25+
FileUtils.rm(file)
26+
end
27+
end
3228

33-
def benchmark_tests
34-
refresh_temp_dir if temp_dir_empty?
35-
system("bundle exec ruby -Ilib:test #{Shellwords.shellescape(TMP_DIR)}/*_benchmark.rb")
36-
end
29+
def fill_temp_dir
30+
Dir[File.join(ROOT, 'test', 'benchmark', '*.rb')].each do |file|
31+
FileUtils.cp(file, File.join(TMP_DIR, File.basename(file)))
32+
end
33+
at_exit { empty_temp_dir }
34+
end
3735

38-
def current_branch
39-
@current_branch ||= `cat .git/HEAD | cut -d/ -f3,4,5`.chomp
40-
end
36+
def refresh_temp_dir
37+
empty_temp_dir
38+
fill_temp_dir
39+
end
4140

42-
def checkout_ref(ref)
43-
puts `git checkout #{ref}`.chomp
44-
abort "Checkout failed: #{ref}, #{$?.exitstatus}" unless $?.success?
45-
end
41+
def benchmark_tests
42+
refresh_temp_dir if temp_dir_empty?
43+
tmp_dir = Shellwords.shellescape(TMP_DIR)
44+
system("#{prepend} bundle exec ruby -Ilib:test #{tmp_dir}/*_benchmark.rb #{append}")
45+
end
4646

47-
def benchmark
48-
refresh_temp_dir
49-
ref = current_branch
47+
def current_branch
48+
@current_branch ||= `cat .git/HEAD | cut -d/ -f3,4,5`.chomp
49+
end
5050

51-
actual = run_benchmark_at_ref ref
52-
master = run_benchmark_at_ref 'master'
51+
def checkout_ref(ref)
52+
puts `git checkout #{ref}`.chomp
53+
abort "Checkout failed: #{ref}, #{$?.exitstatus}" unless $?.success?
54+
end
5355

54-
checkout_ref(ref)
56+
def benchmark_refs(ref1: nil, ref2: nil)
57+
refresh_temp_dir
58+
ref0 = current_branch
59+
ref1 ||= current_branch
60+
ref2 ||= 'master'
5561

56-
puts "\n\nResults ============================\n"
57-
puts "------------------------------------~> (Branch) MASTER"
58-
puts master
59-
puts "------------------------------------\n\n"
62+
actual = run_benchmark_at_ref(ref1)
63+
master = run_benchmark_at_ref(ref2)
6064

61-
puts "------------------------------------~> (Actual Branch) #{ref}"
62-
puts actual
63-
puts "------------------------------------"
64-
end
65+
checkout_ref(ref0)
6566

66-
def run_benchmark
67-
response = Benchmark.realtime {
68-
benchmark_tests
69-
}
70-
benchmark_tests
71-
response
72-
end
67+
puts "\n\nResults ============================\n"
68+
puts "------------------------------------~> (Branch) #{ref1.upcase}"
69+
puts master
70+
puts "------------------------------------\n\n"
71+
72+
puts "------------------------------------~> (Actual Branch) #{ref2.upcase}"
73+
puts actual
74+
puts "------------------------------------"
75+
rescue Exception
76+
checkout_ref(ref0)
77+
raise
78+
end
79+
80+
def run_benchmark
81+
benchmark_tests # warmup
82+
Benchmark.realtime {
83+
benchmark_tests
84+
}
85+
end
7386

74-
def run_benchmark_at_ref(ref)
75-
checkout_ref(ref)
76-
run_benchmark
87+
def run_benchmark_at_ref(ref)
88+
checkout_ref(ref)
89+
run_benchmark
90+
end
7791
end
7892

7993
if $0 == __FILE__
80-
benchmark
94+
benchmarking = Benchmarking.new(append: '> /dev/null')
95+
# Current only
96+
# puts "Ran in #{benchmarking.run_benchmark} seconds."
97+
98+
# Compare ref to master
99+
# Optionally pass in two refs as args to `bin/bench`
100+
benchmarking.benchmark_refs(ref1: ARGV[0], ref2: ARGV[1])
81101
end

test/benchmark/benchmark_helper.rb

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,33 @@
1+
# https://github.com/rails-api/active_model_serializers/pull/872
2+
# approx ref 792fb8a9053f8db3c562dae4f40907a582dd1720 to test against
3+
# require 'test_helper'
14
require 'bundler/setup'
25

36
require 'rails'
4-
abort "Rails application already defined: #{Rails.application.class}" if Rails.application
7+
require 'active_model'
8+
require 'active_support'
9+
require 'active_support/json'
510
require 'action_controller'
611
require 'action_controller/test_case'
712
require 'action_controller/railtie'
8-
require 'active_support/json'
13+
abort "Rails application already defined: #{Rails.application.class}" if Rails.application
914
require 'minitest/autorun'
1015
# Ensure backward compatibility with Minitest 4
1116
Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test)
1217

18+
# ref: https://gist.github.com/bf4/8744473
1319
class BenchmarkApp < Rails::Application
14-
if Rails.version.to_s.start_with? '4'
15-
config.action_controller.perform_caching = true
16-
config.active_support.test_order = :random
17-
ActionController::Base.cache_store = :memory_store
18-
config.eager_load = false
19-
config.secret_key_base = 'abc123'
20-
end
20+
config.action_controller.perform_caching = true
21+
ActionController::Base.cache_store = :memory_store
22+
23+
# Set up production configuration
24+
config.eager_load = true
25+
config.cache_classes = true
26+
27+
config.active_support.test_order = :random
28+
config.secret_token = '1234'
29+
config.secret_key_base = 'abc123'
30+
config.logger = Logger.new(IO::NULL)
2131
end
2232

2333
require 'active_model_serializers'

test/benchmark/fixtures.rb

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ class BlogSerializer < ActiveModel::Serializer
1212
class CommentSerializer < ActiveModel::Serializer
1313
attributes :id, :body
1414

15-
def custom_options
16-
options
17-
end
15+
belongs_to :post
16+
belongs_to :author
1817
end
1918

2019
class PostSerializer < ActiveModel::Serializer
@@ -27,67 +26,81 @@ class PostSerializer < ActiveModel::Serializer
2726
def blog
2827
Blog.new(id: 999, name: 'Custom blog')
2928
end
30-
31-
def custom_options
32-
options
33-
end
3429
end
3530

3631
class CachingAuthorSerializer < AuthorSerializer
37-
cache key: 'writer'
32+
cache key: 'writer', skip_digest: true
3833
end
3934

4035
class CachingCommentSerializer < CommentSerializer
41-
cache expires_in: 1.day
36+
cache expires_in: 1.day, skip_digest: true
4237
end
4338

4439
class CachingPostSerializer < PostSerializer
45-
cache key: 'post', expires_in: 0.1
40+
cache key: 'post', expires_in: 0.1, skip_digest: true
4641
belongs_to :blog, serializer: BlogSerializer
4742
belongs_to :author, serializer: CachingAuthorSerializer
4843
has_many :comments, serializer: CachingCommentSerializer
4944
end
5045

51-
class Model
52-
def initialize(hash = {})
53-
@attributes = hash
46+
# ActiveModelSerializers::Model is a convenient
47+
# serializable class to inherit from when making
48+
# serializable non-activerecord objects.
49+
class BenchmarkModel
50+
include ActiveModel::Model
51+
include ActiveModel::Serializers::JSON
52+
53+
attr_reader :attributes
54+
55+
def initialize(attributes = {})
56+
@attributes = attributes
57+
super
5458
end
5559

60+
# Defaults to the downcased model name.
61+
def id
62+
attributes.fetch(:id) { self.class.name.downcase }
63+
end
64+
65+
# Defaults to the downcased model name and updated_at
5666
def cache_key
57-
"#{self.class.name.downcase}/#{id}-#{updated_at}"
67+
attributes.fetch(:cache_key) { "#{self.class.name.downcase}/#{id}-#{updated_at.strftime("%Y%m%d%H%M%S%9N")}" }
5868
end
5969

70+
# Defaults to the time the serializer file was modified.
6071
def updated_at
61-
@attributes[:updated_at] ||= Time.current.to_i
72+
attributes.fetch(:updated_at) { File.mtime(__FILE__) }
6273
end
6374

64-
def read_attribute_for_serialization(name)
65-
if name == :id || name == 'id'
66-
id
75+
def read_attribute_for_serialization(key)
76+
if key == :id || key == 'id'
77+
attributes.fetch(key) { id }
6778
else
68-
@attributes[name]
79+
attributes[key]
6980
end
7081
end
82+
end
7183

72-
def id
73-
@attributes[:id] || @attributes['id'] || object_id
74-
end
84+
class Comment < BenchmarkModel
85+
attr_accessor :id, :body
7586

76-
def to_param
77-
id
87+
def cache_key
88+
"#{self.class.name.downcase}/#{id}"
7889
end
90+
end
7991

80-
def method_missing(meth, *args)
81-
if meth.to_s =~ /^(.*)=$/
82-
@attributes[Regexp.last_match(1).to_sym] = args[0]
83-
elsif @attributes.key?(meth)
84-
@attributes[meth]
85-
else
86-
super
87-
end
92+
class Author < BenchmarkModel
93+
attr_accessor :id, :name, :posts
94+
end
95+
96+
class Post < BenchmarkModel
97+
attr_accessor :id, :title, :body, :comments, :blog, :author
98+
99+
def cache_key
100+
'benchmarking::post/1-20151215212620000000000'
88101
end
89102
end
90-
class Comment < Model; end
91-
class Author < Model; end
92-
class Post < Model; end
93-
class Blog < Model; end
103+
104+
class Blog < BenchmarkModel
105+
attr_accessor :id, :name
106+
end

0 commit comments

Comments
 (0)