alba 1.0.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +26 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/dependabot.yml +26 -0
- data/.github/workflows/main.yml +10 -1
- data/.github/workflows/perf.yml +21 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +33 -8
- data/.yardopts +2 -0
- data/CHANGELOG.md +45 -0
- data/Gemfile +12 -6
- data/README.md +259 -24
- data/Rakefile +4 -1
- data/SECURITY.md +12 -0
- data/alba.gemspec +3 -3
- data/benchmark/collection.rb +392 -0
- data/benchmark/single_resource.rb +370 -0
- data/codecov.yml +8 -0
- data/gemfiles/all.gemfile +19 -0
- data/gemfiles/without_active_support.gemfile +17 -0
- data/gemfiles/without_oj.gemfile +17 -0
- data/lib/alba.rb +69 -26
- data/lib/alba/association.rb +14 -22
- data/lib/alba/default_inflector.rb +36 -0
- data/lib/alba/key_transform_factory.rb +33 -0
- data/lib/alba/many.rb +3 -2
- data/lib/alba/one.rb +3 -2
- data/lib/alba/resource.rb +171 -62
- data/lib/alba/typed_attribute.rb +61 -0
- data/lib/alba/version.rb +1 -1
- data/script/perf_check.rb +174 -0
- data/sider.yml +2 -4
- metadata +22 -10
- data/benchmark/local.rb +0 -198
- data/lib/alba/key_transformer.rb +0 -31
@@ -0,0 +1,61 @@
|
|
1
|
+
module Alba
|
2
|
+
# Representing typed attributes to encapsulate logic about types
|
3
|
+
class TypedAttribute
|
4
|
+
# @param name [Symbol, String]
|
5
|
+
# @param type [Symbol, Class]
|
6
|
+
# @param converter [Proc]
|
7
|
+
def initialize(name:, type:, converter:)
|
8
|
+
@name = name
|
9
|
+
@type = type
|
10
|
+
@converter = case converter
|
11
|
+
when true then default_converter
|
12
|
+
when false, nil then null_converter
|
13
|
+
else converter
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param object [Object] target to check and convert type with
|
18
|
+
# @return [String, Integer, Boolean] type-checked or type-converted object
|
19
|
+
def value(object)
|
20
|
+
value, result = check(object)
|
21
|
+
result ? value : @converter.call(value)
|
22
|
+
rescue TypeError
|
23
|
+
raise TypeError, "Attribute #{@name} is expected to be #{@type} but actually #{display_value_for(value)}."
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def check(object)
|
29
|
+
value = object.public_send(@name)
|
30
|
+
type_correct = case @type
|
31
|
+
when :String, ->(klass) { klass == String } then value.is_a?(String)
|
32
|
+
when :Integer, ->(klass) { klass == Integer } then value.is_a?(Integer)
|
33
|
+
when :Boolean then [true, false].include?(value)
|
34
|
+
else
|
35
|
+
raise Alba::UnsupportedType, "Unknown type: #{@type}"
|
36
|
+
end
|
37
|
+
[value, type_correct]
|
38
|
+
end
|
39
|
+
|
40
|
+
def default_converter
|
41
|
+
case @type
|
42
|
+
when :String, ->(klass) { klass == String }
|
43
|
+
->(object) { object.to_s }
|
44
|
+
when :Integer, ->(klass) { klass == Integer }
|
45
|
+
->(object) { Integer(object) }
|
46
|
+
when :Boolean
|
47
|
+
->(object) { !!object }
|
48
|
+
else
|
49
|
+
raise Alba::UnsupportedType, "Unknown type: #{@type}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def null_converter
|
54
|
+
->(_) { raise TypeError }
|
55
|
+
end
|
56
|
+
|
57
|
+
def display_value_for(value)
|
58
|
+
value.nil? ? 'nil' : value.class.name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/alba/version.rb
CHANGED
@@ -0,0 +1,174 @@
|
|
1
|
+
# Benchmark script to run varieties of JSON serializers
|
2
|
+
# Fetch Alba from local, otherwise fetch latest from RubyGems
|
3
|
+
# exit(status)
|
4
|
+
|
5
|
+
# --- Bundle dependencies ---
|
6
|
+
|
7
|
+
require "bundler/inline"
|
8
|
+
|
9
|
+
gemfile(true) do
|
10
|
+
source "https://rubygems.org"
|
11
|
+
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
12
|
+
|
13
|
+
gem "activerecord", "~> 6.1.3"
|
14
|
+
gem "alba", path: '../'
|
15
|
+
gem "benchmark-ips"
|
16
|
+
gem "blueprinter"
|
17
|
+
gem "jbuilder"
|
18
|
+
gem "multi_json"
|
19
|
+
gem "oj"
|
20
|
+
gem "sqlite3"
|
21
|
+
end
|
22
|
+
|
23
|
+
# --- Test data model setup ---
|
24
|
+
|
25
|
+
require "active_record"
|
26
|
+
require "oj"
|
27
|
+
require "sqlite3"
|
28
|
+
Oj.optimize_rails
|
29
|
+
|
30
|
+
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
31
|
+
|
32
|
+
ActiveRecord::Schema.define do
|
33
|
+
create_table :posts, force: true do |t|
|
34
|
+
t.string :body
|
35
|
+
end
|
36
|
+
|
37
|
+
create_table :comments, force: true do |t|
|
38
|
+
t.integer :post_id
|
39
|
+
t.string :body
|
40
|
+
t.integer :commenter_id
|
41
|
+
end
|
42
|
+
|
43
|
+
create_table :users, force: true do |t|
|
44
|
+
t.string :name
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Post < ActiveRecord::Base
|
49
|
+
has_many :comments
|
50
|
+
has_many :commenters, through: :comments, class_name: 'User', source: :commenter
|
51
|
+
|
52
|
+
def attributes
|
53
|
+
{id: nil, body: nil, commenter_names: commenter_names}
|
54
|
+
end
|
55
|
+
|
56
|
+
def commenter_names
|
57
|
+
commenters.pluck(:name)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Comment < ActiveRecord::Base
|
62
|
+
belongs_to :post
|
63
|
+
belongs_to :commenter, class_name: 'User'
|
64
|
+
|
65
|
+
def attributes
|
66
|
+
{id: nil, body: nil}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class User < ActiveRecord::Base
|
71
|
+
has_many :comments
|
72
|
+
end
|
73
|
+
|
74
|
+
# --- Alba serializers ---
|
75
|
+
|
76
|
+
require "alba"
|
77
|
+
|
78
|
+
class AlbaCommentResource
|
79
|
+
include ::Alba::Resource
|
80
|
+
attributes :id, :body
|
81
|
+
end
|
82
|
+
|
83
|
+
class AlbaPostResource
|
84
|
+
include ::Alba::Resource
|
85
|
+
attributes :id, :body
|
86
|
+
attribute :commenter_names do |post|
|
87
|
+
post.commenters.pluck(:name)
|
88
|
+
end
|
89
|
+
many :comments, resource: AlbaCommentResource
|
90
|
+
end
|
91
|
+
|
92
|
+
# --- Blueprint serializers ---
|
93
|
+
|
94
|
+
require "blueprinter"
|
95
|
+
|
96
|
+
class CommentBlueprint < Blueprinter::Base
|
97
|
+
fields :id, :body
|
98
|
+
end
|
99
|
+
|
100
|
+
class PostBlueprint < Blueprinter::Base
|
101
|
+
fields :id, :body, :commenter_names
|
102
|
+
association :comments, blueprint: CommentBlueprint
|
103
|
+
|
104
|
+
def commenter_names
|
105
|
+
commenters.pluck(:name)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# --- JBuilder serializers ---
|
110
|
+
|
111
|
+
require "jbuilder"
|
112
|
+
|
113
|
+
class Post
|
114
|
+
def to_builder
|
115
|
+
Jbuilder.new do |post|
|
116
|
+
post.call(self, :id, :body, :commenter_names, :comments)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def commenter_names
|
121
|
+
commenters.pluck(:name)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class Comment
|
126
|
+
def to_builder
|
127
|
+
Jbuilder.new do |comment|
|
128
|
+
comment.call(self, :id, :body)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# --- Test data creation ---
|
134
|
+
|
135
|
+
100.times do |i|
|
136
|
+
post = Post.create!(body: "post#{i}")
|
137
|
+
user1 = User.create!(name: "John#{i}")
|
138
|
+
user2 = User.create!(name: "Jane#{i}")
|
139
|
+
10.times do |n|
|
140
|
+
post.comments.create!(commenter: user1, body: "Comment1_#{i}_#{n}")
|
141
|
+
post.comments.create!(commenter: user2, body: "Comment2_#{i}_#{n}")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
posts = Post.all.to_a
|
146
|
+
|
147
|
+
# --- Store the serializers in procs ---
|
148
|
+
|
149
|
+
alba = Proc.new { AlbaPostResource.new(posts).serialize }
|
150
|
+
blueprinter = Proc.new { PostBlueprint.render(posts) }
|
151
|
+
jbuilder = Proc.new do
|
152
|
+
Jbuilder.new do |json|
|
153
|
+
json.array!(posts) do |post|
|
154
|
+
json.post post.to_builder
|
155
|
+
end
|
156
|
+
end.target!
|
157
|
+
end
|
158
|
+
|
159
|
+
# --- Run the benchmarks ---
|
160
|
+
|
161
|
+
require 'benchmark/ips'
|
162
|
+
result = Benchmark.ips do |x|
|
163
|
+
x.report(:alba, &alba)
|
164
|
+
x.report(:blueprinter, &blueprinter)
|
165
|
+
x.report(:jbuilder, &jbuilder)
|
166
|
+
end
|
167
|
+
|
168
|
+
entries = result.entries.map {|entry| [entry.label, entry.iterations]}
|
169
|
+
alba_ips = entries.find {|e| e.first == :alba }.last
|
170
|
+
blueprinter_ips = entries.find {|e| e.first == :blueprinter }.last
|
171
|
+
jbuidler_ips = entries.find {|e| e.first == :jbuilder }.last
|
172
|
+
# Alba should be as fast as jbuilder and faster than blueprinter
|
173
|
+
alba_is_fast_enough = (alba_ips - jbuidler_ips) > -10.0 && (alba_ips - blueprinter_ips) > 10.0
|
174
|
+
exit(alba_is_fast_enough)
|
data/sider.yml
CHANGED
@@ -49,10 +49,8 @@ linter:
|
|
49
49
|
# norc: true
|
50
50
|
|
51
51
|
# # https://help.sider.review/getting-started/custom-configuration#ignore
|
52
|
-
|
53
|
-
|
54
|
-
# - "*.mp4"
|
55
|
-
# - "images/**"
|
52
|
+
ignore:
|
53
|
+
- 'test/**/*'
|
56
54
|
|
57
55
|
# # https://help.sider.review/getting-started/custom-configuration#branchesexclude
|
58
56
|
# branches:
|
metadata
CHANGED
@@ -1,25 +1,28 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alba
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OKURA Masafumi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: Alba is
|
14
|
-
|
15
|
-
do similar things. The internal is so simple that it's easy to hack and maintain.
|
13
|
+
description: Alba is the fastest JSON serializer for Ruby. It focuses on performance,
|
14
|
+
flexibility and usability.
|
16
15
|
email:
|
17
16
|
- masafumi.o1988@gmail.com
|
18
17
|
executables: []
|
19
18
|
extensions: []
|
20
19
|
extra_rdoc_files: []
|
21
20
|
files:
|
21
|
+
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
22
|
+
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
23
|
+
- ".github/dependabot.yml"
|
22
24
|
- ".github/workflows/main.yml"
|
25
|
+
- ".github/workflows/perf.yml"
|
23
26
|
- ".gitignore"
|
24
27
|
- ".rubocop.yml"
|
25
28
|
- ".yardopts"
|
@@ -29,17 +32,26 @@ files:
|
|
29
32
|
- LICENSE.txt
|
30
33
|
- README.md
|
31
34
|
- Rakefile
|
35
|
+
- SECURITY.md
|
32
36
|
- alba.gemspec
|
33
|
-
- benchmark/
|
37
|
+
- benchmark/collection.rb
|
38
|
+
- benchmark/single_resource.rb
|
34
39
|
- bin/console
|
35
40
|
- bin/setup
|
41
|
+
- codecov.yml
|
42
|
+
- gemfiles/all.gemfile
|
43
|
+
- gemfiles/without_active_support.gemfile
|
44
|
+
- gemfiles/without_oj.gemfile
|
36
45
|
- lib/alba.rb
|
37
46
|
- lib/alba/association.rb
|
38
|
-
- lib/alba/
|
47
|
+
- lib/alba/default_inflector.rb
|
48
|
+
- lib/alba/key_transform_factory.rb
|
39
49
|
- lib/alba/many.rb
|
40
50
|
- lib/alba/one.rb
|
41
51
|
- lib/alba/resource.rb
|
52
|
+
- lib/alba/typed_attribute.rb
|
42
53
|
- lib/alba/version.rb
|
54
|
+
- script/perf_check.rb
|
43
55
|
- sider.yml
|
44
56
|
homepage: https://github.com/okuramasafumi/alba
|
45
57
|
licenses:
|
@@ -47,7 +59,7 @@ licenses:
|
|
47
59
|
metadata:
|
48
60
|
homepage_uri: https://github.com/okuramasafumi/alba
|
49
61
|
source_code_uri: https://github.com/okuramasafumi/alba
|
50
|
-
changelog_uri: https://github.com/okuramasafumi/alba/CHANGELOG.md
|
62
|
+
changelog_uri: https://github.com/okuramasafumi/alba/blob/main/CHANGELOG.md
|
51
63
|
post_install_message:
|
52
64
|
rdoc_options: []
|
53
65
|
require_paths:
|
@@ -56,14 +68,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
56
68
|
requirements:
|
57
69
|
- - ">="
|
58
70
|
- !ruby/object:Gem::Version
|
59
|
-
version: 2.5.
|
71
|
+
version: 2.5.0
|
60
72
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
73
|
requirements:
|
62
74
|
- - ">="
|
63
75
|
- !ruby/object:Gem::Version
|
64
76
|
version: '0'
|
65
77
|
requirements: []
|
66
|
-
rubygems_version: 3.2.
|
78
|
+
rubygems_version: 3.2.16
|
67
79
|
signing_key:
|
68
80
|
specification_version: 4
|
69
81
|
summary: Alba is the fastest JSON serializer for Ruby.
|
data/benchmark/local.rb
DELETED
@@ -1,198 +0,0 @@
|
|
1
|
-
# Benchmark script to run varieties of JSON serializers
|
2
|
-
# Fetch Alba from local, otherwise fetch latest from RubyGems
|
3
|
-
|
4
|
-
require "bundler/inline"
|
5
|
-
|
6
|
-
gemfile(true) do
|
7
|
-
source "https://rubygems.org"
|
8
|
-
|
9
|
-
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
10
|
-
|
11
|
-
gem "activerecord", "6.1.3"
|
12
|
-
gem "sqlite3"
|
13
|
-
gem "jbuilder"
|
14
|
-
gem "active_model_serializers"
|
15
|
-
gem "blueprinter"
|
16
|
-
gem "representable"
|
17
|
-
gem "alba", path: '../'
|
18
|
-
gem "oj"
|
19
|
-
gem "multi_json"
|
20
|
-
end
|
21
|
-
|
22
|
-
require "active_record"
|
23
|
-
require "sqlite3"
|
24
|
-
require "logger"
|
25
|
-
require "oj"
|
26
|
-
Oj.optimize_rails
|
27
|
-
|
28
|
-
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
29
|
-
# ActiveRecord::Base.logger = Logger.new(STDOUT)
|
30
|
-
|
31
|
-
ActiveRecord::Schema.define do
|
32
|
-
create_table :posts, force: true do |t|
|
33
|
-
t.string :body
|
34
|
-
end
|
35
|
-
|
36
|
-
create_table :comments, force: true do |t|
|
37
|
-
t.integer :post_id
|
38
|
-
t.string :body
|
39
|
-
t.integer :commenter_id
|
40
|
-
end
|
41
|
-
|
42
|
-
create_table :users, force: true do |t|
|
43
|
-
t.string :name
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
class Post < ActiveRecord::Base
|
48
|
-
has_many :comments
|
49
|
-
has_many :commenters, through: :comments, class_name: 'User', source: :commenter
|
50
|
-
|
51
|
-
def attributes
|
52
|
-
{id: nil, body: nil, commenter_names: commenter_names}
|
53
|
-
end
|
54
|
-
|
55
|
-
def commenter_names
|
56
|
-
commenters.pluck(:name)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
class Comment < ActiveRecord::Base
|
61
|
-
belongs_to :post
|
62
|
-
belongs_to :commenter, class_name: 'User'
|
63
|
-
|
64
|
-
def attributes
|
65
|
-
{id: nil, body: nil}
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
class User < ActiveRecord::Base
|
70
|
-
has_many :comments
|
71
|
-
end
|
72
|
-
|
73
|
-
require "alba"
|
74
|
-
Alba.backend = :oj
|
75
|
-
|
76
|
-
class AlbaCommentResource
|
77
|
-
include ::Alba::Resource
|
78
|
-
attributes :id, :body
|
79
|
-
end
|
80
|
-
|
81
|
-
class AlbaPostResource
|
82
|
-
include ::Alba::Resource
|
83
|
-
attributes :id, :body
|
84
|
-
many :comments, resource: AlbaCommentResource
|
85
|
-
attribute :commenter_names do |post|
|
86
|
-
post.commenters.pluck(:name)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
require "jbuilder"
|
91
|
-
class Post
|
92
|
-
def to_builder
|
93
|
-
Jbuilder.new do |post|
|
94
|
-
post.call(self, :id, :body, :comments, :commenter_names)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def commenter_names
|
99
|
-
commenters.pluck(:name)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
class Comment
|
104
|
-
def to_builder
|
105
|
-
Jbuilder.new do |comment|
|
106
|
-
comment.call(self, :id, :body)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
require "active_model_serializers"
|
112
|
-
|
113
|
-
class AMSCommentSerializer < ActiveModel::Serializer
|
114
|
-
attributes :id, :body
|
115
|
-
end
|
116
|
-
|
117
|
-
class AMSPostSerializer < ActiveModel::Serializer
|
118
|
-
attributes :id, :body
|
119
|
-
has_many :comments, serializer: AMSCommentSerializer
|
120
|
-
attribute :commenter_names
|
121
|
-
def commenter_names
|
122
|
-
object.commenters.pluck(:name)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
require "blueprinter"
|
127
|
-
|
128
|
-
class CommentBlueprint < Blueprinter::Base
|
129
|
-
fields :id, :body
|
130
|
-
end
|
131
|
-
|
132
|
-
class PostBlueprint < Blueprinter::Base
|
133
|
-
fields :id, :body, :commenter_names
|
134
|
-
association :comments, blueprint: CommentBlueprint
|
135
|
-
def commenter_names
|
136
|
-
commenters.pluck(:name)
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
require "representable"
|
141
|
-
|
142
|
-
class CommentRepresenter < Representable::Decorator
|
143
|
-
include Representable::JSON
|
144
|
-
|
145
|
-
property :id
|
146
|
-
property :body
|
147
|
-
end
|
148
|
-
|
149
|
-
class PostRepresenter < Representable::Decorator
|
150
|
-
include Representable::JSON
|
151
|
-
|
152
|
-
property :id
|
153
|
-
property :body
|
154
|
-
property :commenter_names
|
155
|
-
collection :comments
|
156
|
-
|
157
|
-
def commenter_names
|
158
|
-
commenters.pluck(:name)
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
post = Post.create!(body: 'post')
|
163
|
-
user1 = User.create!(name: 'John')
|
164
|
-
user2 = User.create!(name: 'Jane')
|
165
|
-
post.comments.create!(commenter: user1, body: 'Comment1')
|
166
|
-
post.comments.create!(commenter: user2, body: 'Comment2')
|
167
|
-
post.reload
|
168
|
-
|
169
|
-
alba = Proc.new { AlbaPostResource.new(post).serialize }
|
170
|
-
jbuilder = Proc.new { post.to_builder.target! }
|
171
|
-
ams = Proc.new { AMSPostSerializer.new(post, {}).to_json }
|
172
|
-
rails = Proc.new { ActiveSupport::JSON.encode(post.serializable_hash(include: :comments)) }
|
173
|
-
blueprinter = Proc.new { PostBlueprint.render(post) }
|
174
|
-
representable = Proc.new { PostRepresenter.new(post).to_json }
|
175
|
-
alba_inline = Proc.new do
|
176
|
-
Alba.serialize(post) do
|
177
|
-
attributes :id, :body
|
178
|
-
attribute :commenter_names do |post|
|
179
|
-
post.commenters.pluck(:name)
|
180
|
-
end
|
181
|
-
many :comments do
|
182
|
-
attributes :id, :body
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
[alba, jbuilder, ams, rails, blueprinter, representable, alba_inline].each {|x| puts x.call }
|
187
|
-
|
188
|
-
require 'benchmark'
|
189
|
-
time = 1000
|
190
|
-
Benchmark.bmbm do |x|
|
191
|
-
x.report(:alba) { time.times(&alba) }
|
192
|
-
x.report(:jbuilder) { time.times(&jbuilder) }
|
193
|
-
x.report(:ams) { time.times(&ams) }
|
194
|
-
x.report(:rails) { time.times(&rails) }
|
195
|
-
x.report(:blueprinter) { time.times(&blueprinter) }
|
196
|
-
x.report(:representable) { time.times(&representable) }
|
197
|
-
x.report(:alba_inline) { time.times(&alba_inline) }
|
198
|
-
end
|