mr 0.35.2
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 +7 -0
- data/.gitignore +19 -0
- data/Gemfile +13 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/bench/all.rb +4 -0
- data/bench/factory.rb +68 -0
- data/bench/fake_record.rb +174 -0
- data/bench/model.rb +201 -0
- data/bench/read_model.rb +191 -0
- data/bench/results/factory.txt +21 -0
- data/bench/results/fake_record.txt +37 -0
- data/bench/results/model.txt +44 -0
- data/bench/results/read_model.txt +46 -0
- data/bench/setup.rb +132 -0
- data/lib/mr.rb +11 -0
- data/lib/mr/after_commit.rb +49 -0
- data/lib/mr/after_commit/fake_record.rb +39 -0
- data/lib/mr/after_commit/record.rb +48 -0
- data/lib/mr/after_commit/record_procs_methods.rb +82 -0
- data/lib/mr/factory.rb +82 -0
- data/lib/mr/factory/config.rb +240 -0
- data/lib/mr/factory/model_factory.rb +103 -0
- data/lib/mr/factory/model_stack.rb +28 -0
- data/lib/mr/factory/read_model_factory.rb +104 -0
- data/lib/mr/factory/record_factory.rb +130 -0
- data/lib/mr/factory/record_stack.rb +219 -0
- data/lib/mr/fake_query.rb +53 -0
- data/lib/mr/fake_record.rb +58 -0
- data/lib/mr/fake_record/associations.rb +257 -0
- data/lib/mr/fake_record/attributes.rb +168 -0
- data/lib/mr/fake_record/persistence.rb +116 -0
- data/lib/mr/json_field.rb +180 -0
- data/lib/mr/json_field/fake_record.rb +31 -0
- data/lib/mr/json_field/record.rb +38 -0
- data/lib/mr/model.rb +67 -0
- data/lib/mr/model/associations.rb +161 -0
- data/lib/mr/model/configuration.rb +67 -0
- data/lib/mr/model/fields.rb +177 -0
- data/lib/mr/model/persistence.rb +79 -0
- data/lib/mr/query.rb +126 -0
- data/lib/mr/read_model.rb +83 -0
- data/lib/mr/read_model/data.rb +38 -0
- data/lib/mr/read_model/fields.rb +218 -0
- data/lib/mr/read_model/query_expression.rb +188 -0
- data/lib/mr/read_model/querying.rb +214 -0
- data/lib/mr/read_model/set_querying.rb +82 -0
- data/lib/mr/read_model/subquery.rb +98 -0
- data/lib/mr/record.rb +35 -0
- data/lib/mr/test_helpers.rb +229 -0
- data/lib/mr/type_converter.rb +85 -0
- data/lib/mr/version.rb +3 -0
- data/log/.gitkeep +0 -0
- data/mr.gemspec +29 -0
- data/test/helper.rb +21 -0
- data/test/support/db.rb +10 -0
- data/test/support/factory.rb +13 -0
- data/test/support/factory/area.rb +6 -0
- data/test/support/factory/comment.rb +14 -0
- data/test/support/factory/image.rb +6 -0
- data/test/support/factory/user.rb +6 -0
- data/test/support/models/area.rb +58 -0
- data/test/support/models/comment.rb +60 -0
- data/test/support/models/image.rb +53 -0
- data/test/support/models/user.rb +96 -0
- data/test/support/read_model/querying.rb +150 -0
- data/test/support/read_models/comment_with_user_data.rb +27 -0
- data/test/support/read_models/set_data.rb +49 -0
- data/test/support/read_models/subquery_data.rb +41 -0
- data/test/support/read_models/user_with_area_data.rb +15 -0
- data/test/support/schema.rb +39 -0
- data/test/support/setup_test_db.rb +10 -0
- data/test/system/factory/model_factory_tests.rb +87 -0
- data/test/system/factory/model_stack_tests.rb +30 -0
- data/test/system/factory/record_factory_tests.rb +84 -0
- data/test/system/factory/record_stack_tests.rb +51 -0
- data/test/system/factory_tests.rb +32 -0
- data/test/system/read_model_tests.rb +199 -0
- data/test/system/with_model_tests.rb +275 -0
- data/test/unit/after_commit/fake_record_tests.rb +110 -0
- data/test/unit/after_commit/record_procs_methods_tests.rb +177 -0
- data/test/unit/after_commit/record_tests.rb +134 -0
- data/test/unit/after_commit_tests.rb +113 -0
- data/test/unit/factory/config_tests.rb +651 -0
- data/test/unit/factory/model_factory_tests.rb +473 -0
- data/test/unit/factory/model_stack_tests.rb +97 -0
- data/test/unit/factory/read_model_factory_tests.rb +195 -0
- data/test/unit/factory/record_factory_tests.rb +446 -0
- data/test/unit/factory/record_stack_tests.rb +549 -0
- data/test/unit/factory_tests.rb +213 -0
- data/test/unit/fake_query_tests.rb +137 -0
- data/test/unit/fake_record/associations_tests.rb +585 -0
- data/test/unit/fake_record/attributes_tests.rb +265 -0
- data/test/unit/fake_record/persistence_tests.rb +239 -0
- data/test/unit/fake_record_tests.rb +106 -0
- data/test/unit/json_field/fake_record_tests.rb +75 -0
- data/test/unit/json_field/record_tests.rb +80 -0
- data/test/unit/json_field_tests.rb +302 -0
- data/test/unit/model/associations_tests.rb +346 -0
- data/test/unit/model/configuration_tests.rb +92 -0
- data/test/unit/model/fields_tests.rb +278 -0
- data/test/unit/model/persistence_tests.rb +114 -0
- data/test/unit/model_tests.rb +137 -0
- data/test/unit/query_tests.rb +300 -0
- data/test/unit/read_model/data_tests.rb +56 -0
- data/test/unit/read_model/fields_tests.rb +416 -0
- data/test/unit/read_model/query_expression_tests.rb +381 -0
- data/test/unit/read_model/querying_tests.rb +613 -0
- data/test/unit/read_model/set_querying_tests.rb +149 -0
- data/test/unit/read_model/subquery_tests.rb +242 -0
- data/test/unit/read_model_tests.rb +187 -0
- data/test/unit/record_tests.rb +45 -0
- data/test/unit/test_helpers_tests.rb +431 -0
- data/test/unit/type_converter_tests.rb +207 -0
- metadata +285 -0
data/bench/read_model.rb
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
$LOAD_PATH.push File.expand_path('../..', __FILE__)
|
2
|
+
require 'bench/setup'
|
3
|
+
|
4
|
+
profiler = Bench::Profiler.new("bench/results/read_model.txt")
|
5
|
+
profiler.run("MR::ReadModel") do
|
6
|
+
|
7
|
+
section "Fields" do
|
8
|
+
read_model_class = Class.new{ include MR::ReadModel }
|
9
|
+
|
10
|
+
benchmark("field") do |n|
|
11
|
+
read_model_class.field "field_#{n}", :string
|
12
|
+
end
|
13
|
+
benchmark("field with select args") do |n|
|
14
|
+
read_model_class.field "field_args_#{n}", :string, "column_#{n}"
|
15
|
+
end
|
16
|
+
benchmark("field with select block") do |n|
|
17
|
+
read_model_class.field("field_block_#{n}", :string){ |c| "table.#{c}" }
|
18
|
+
end
|
19
|
+
|
20
|
+
read_model_class = Class.new do
|
21
|
+
include MR::ReadModel
|
22
|
+
field :string, :string
|
23
|
+
field :text, :text
|
24
|
+
field :binary, :binary
|
25
|
+
field :integer, :integer
|
26
|
+
field :primary_key, :primary_key
|
27
|
+
field :float, :float
|
28
|
+
field :decimal, :decimal
|
29
|
+
field :datetime, :datetime
|
30
|
+
field :timestamp, :timestamp
|
31
|
+
field :time, :time
|
32
|
+
field :date, :date
|
33
|
+
field :boolean, :boolean
|
34
|
+
end
|
35
|
+
|
36
|
+
benchmark("typecast string") do |n|
|
37
|
+
read_model = read_model_class.new('string' => 'String')
|
38
|
+
read_model.string
|
39
|
+
end
|
40
|
+
benchmark("typecast text") do |n|
|
41
|
+
read_model = read_model_class.new('text' => 'Text')
|
42
|
+
read_model.text
|
43
|
+
end
|
44
|
+
benchmark("typecast binary") do |n|
|
45
|
+
read_model = read_model_class.new('binary' => "\000\001\002\003\004")
|
46
|
+
read_model.binary
|
47
|
+
end
|
48
|
+
benchmark("typecast integer") do |n|
|
49
|
+
read_model = read_model_class.new('integer' => '100')
|
50
|
+
read_model.integer
|
51
|
+
end
|
52
|
+
benchmark("typecast primary key") do |n|
|
53
|
+
read_model = read_model_class.new('primary_key' => '125')
|
54
|
+
read_model.primary_key
|
55
|
+
end
|
56
|
+
benchmark("typecast float") do |n|
|
57
|
+
read_model = read_model_class.new('float' => '6.1370')
|
58
|
+
read_model.float
|
59
|
+
end
|
60
|
+
benchmark("typecast decimal") do |n|
|
61
|
+
read_model = read_model_class.new('decimal' => '33.4755926134924')
|
62
|
+
read_model.decimal
|
63
|
+
end
|
64
|
+
benchmark("typecast datetime") do |n|
|
65
|
+
read_model = read_model_class.new('datetime' => '2013-11-18 21:29:10')
|
66
|
+
read_model.datetime
|
67
|
+
end
|
68
|
+
benchmark("typecast timestamp") do |n|
|
69
|
+
read_model = read_model_class.new('timestamp' => '2013-11-18 22:10:36.660846')
|
70
|
+
read_model.timestamp
|
71
|
+
end
|
72
|
+
benchmark("typecast time") do |n|
|
73
|
+
read_model = read_model_class.new('time' => '21:29:10.905011')
|
74
|
+
read_model.time
|
75
|
+
end
|
76
|
+
benchmark("typecast date") do |n|
|
77
|
+
read_model = read_model_class.new('date' => '2013-11-18')
|
78
|
+
read_model.date
|
79
|
+
end
|
80
|
+
benchmark("typecast boolean") do |n|
|
81
|
+
read_model = read_model_class.new('boolean' => 't')
|
82
|
+
read_model.boolean
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
section "Querying" do
|
88
|
+
read_model_class = Class.new{ include MR::ReadModel }
|
89
|
+
|
90
|
+
benchmark("select") do |n|
|
91
|
+
read_model_class.select "column_#{n}"
|
92
|
+
end
|
93
|
+
benchmark("select with block") do |n|
|
94
|
+
read_model_class.select{ |column| "table.#{column}" }
|
95
|
+
end
|
96
|
+
benchmark("from") do |n|
|
97
|
+
read_model_class.from((n % 2 == 0) ? UserRecord : AreaRecord)
|
98
|
+
end
|
99
|
+
benchmark("joins") do |n|
|
100
|
+
read_model_class.joins "table_#{n}"
|
101
|
+
end
|
102
|
+
benchmark("joins with block") do |n|
|
103
|
+
read_model_class.joins{ |table| table }
|
104
|
+
end
|
105
|
+
benchmark("where") do |n|
|
106
|
+
read_model_class.where :column => n
|
107
|
+
end
|
108
|
+
benchmark("where with block") do |n|
|
109
|
+
read_model_class.where{ |value| { :column => value } }
|
110
|
+
end
|
111
|
+
benchmark("order") do |n|
|
112
|
+
read_model_class.order "column_#{n}"
|
113
|
+
end
|
114
|
+
benchmark("order with block") do |n|
|
115
|
+
read_model_class.order{ |column| "table.#{column}" }
|
116
|
+
end
|
117
|
+
benchmark("group") do |n|
|
118
|
+
read_model_class.group "column_#{n}"
|
119
|
+
end
|
120
|
+
benchmark("group with block") do |n|
|
121
|
+
read_model_class.group{ |column| "table.#{column}" }
|
122
|
+
end
|
123
|
+
benchmark("having") do |n|
|
124
|
+
read_model_class.having "COUNT(column_#{n})"
|
125
|
+
end
|
126
|
+
benchmark("having with block") do |n|
|
127
|
+
read_model_class.having{ |column| "COUNT(table.#{column})" }
|
128
|
+
end
|
129
|
+
benchmark("limit") do |n|
|
130
|
+
read_model_class.limit n
|
131
|
+
end
|
132
|
+
benchmark("limit with block") do |n|
|
133
|
+
read_model_class.limit{ |count| count }
|
134
|
+
end
|
135
|
+
benchmark("offset") do |n|
|
136
|
+
read_model_class.offset n
|
137
|
+
end
|
138
|
+
benchmark("offset with block") do |n|
|
139
|
+
read_model_class.offset{ |count| count }
|
140
|
+
end
|
141
|
+
benchmark("merge") do |n|
|
142
|
+
read_model_class.merge((n % 2 == 0) ? UserRecord.scoped : AreaRecord.scoped)
|
143
|
+
end
|
144
|
+
benchmark("merge with block") do |n|
|
145
|
+
read_model_class.merge{ |value| AreaRecord.scoped }
|
146
|
+
end
|
147
|
+
benchmark("inner join subquery") do |n|
|
148
|
+
read_model_class.inner_join_subquery do
|
149
|
+
read_model{ from AreaRecord }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
benchmark("left outer join subquery") do |n|
|
153
|
+
read_model_class.left_outer_join_subquery do
|
154
|
+
read_model{ from AreaRecord }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
benchmark("right outer join subquery") do |n|
|
158
|
+
read_model_class.right_outer_join_subquery do
|
159
|
+
read_model{ from AreaRecord }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
benchmark("full outer join subquery") do |n|
|
163
|
+
read_model_class.full_outer_join_subquery do
|
164
|
+
read_model{ from AreaRecord }
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
first_area = AreaRecord.new(:name => 'Area1').tap(&:save)
|
169
|
+
second_area = AreaRecord.new(:name => 'Area2').tap(&:save)
|
170
|
+
first_user = UserRecord.new(:name => 'User1').tap do |u|
|
171
|
+
u.area = first_area
|
172
|
+
u.save
|
173
|
+
end
|
174
|
+
second_user = UserRecord.new(:name => 'User2').tap do |u|
|
175
|
+
u.area = second_area
|
176
|
+
u.save
|
177
|
+
end
|
178
|
+
comment = CommentRecord.new(:parent => first_user).tap(&:save)
|
179
|
+
|
180
|
+
benchmark("find") do
|
181
|
+
UserWithAreaData.find(first_user.id)
|
182
|
+
end
|
183
|
+
benchmark("query") do
|
184
|
+
UserWithAreaData.query.results
|
185
|
+
end
|
186
|
+
benchmark("subquery query") do
|
187
|
+
SubqueryData.query(:started_on => first_user.started_on).results
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
MR::Factory
|
2
|
+
-----------
|
3
|
+
primary_key new provider | 62.22 ms | 1.69 MB |
|
4
|
+
primary_key existing provider | 33.6 ms | 0.0 MB |
|
5
|
+
integer | 22.66 ms | 0.0 MB |
|
6
|
+
float | 22.03 ms | 0.0 MB |
|
7
|
+
decimal | 61.53 ms | 0.35 MB |
|
8
|
+
date | 76.27 ms | 0.41 MB |
|
9
|
+
datetime | 27.89 ms | 0.0 MB |
|
10
|
+
time | 32.05 ms | 0.0 MB |
|
11
|
+
timestamp | 31.0 ms | 0.77 MB |
|
12
|
+
string | 95.36 ms | 2.93 MB |
|
13
|
+
text | 149.15 ms | 1.42 MB |
|
14
|
+
slug | 126.49 ms | 1.14 MB |
|
15
|
+
hex | 136.85 ms | 0.96 MB |
|
16
|
+
file_name | 124.49 ms | 2.59 MB |
|
17
|
+
dir_path | 159.27 ms | 0.92 MB |
|
18
|
+
file_path | 289.76 ms | 23.92 MB |
|
19
|
+
binary | 31.31 ms | 0.59 MB |
|
20
|
+
boolean | 25.62 ms | 0.0 MB |
|
21
|
+
Total | 2.43 s | 33.33 MB |
|
@@ -0,0 +1,37 @@
|
|
1
|
+
MR::FakeRecord
|
2
|
+
--------------
|
3
|
+
Initialization
|
4
|
+
initialize with no arguments | 19.78 ms | 1.27 MB |
|
5
|
+
initialize with a hash | 93.43 ms | 0.79 MB |
|
6
|
+
Comparison
|
7
|
+
== unequal | 7.12 ms | 0.02 MB |
|
8
|
+
== equal | 7.36 ms | 0.0 MB |
|
9
|
+
Attributes
|
10
|
+
attribute | 403.95 ms | 131.0 MB |
|
11
|
+
read single attribute | 1.87 ms | 0.02 MB |
|
12
|
+
write single attribute | 11.93 ms | 0.0 MB |
|
13
|
+
read single attribute was | 15.17 ms | 0.0 MB |
|
14
|
+
single attribute changed? | 22.97 ms | 0.0 MB |
|
15
|
+
attributes | 186.34 ms | 25.01 MB |
|
16
|
+
attributes= | 85.33 ms | 0.84 MB |
|
17
|
+
columns | 48.05 ms | 0.0 MB |
|
18
|
+
Associations
|
19
|
+
belongs_to | 311.59 ms | 101.88 MB |
|
20
|
+
has_many | 348.34 ms | 5.81 MB |
|
21
|
+
has_one | 376.29 ms | 112.59 MB |
|
22
|
+
polymorphic_belongs_to | 340.73 ms | 120.84 MB |
|
23
|
+
read belongs to | 23.1 ms | 0.0 MB |
|
24
|
+
write belongs to | 58.97 ms | 0.05 MB |
|
25
|
+
read has many | 24.1 ms | 0.0 MB |
|
26
|
+
write has many | 47.59 ms | 0.0 MB |
|
27
|
+
read has one | 21.69 ms | 0.0 MB |
|
28
|
+
write has one | 29.72 ms | 0.1 MB |
|
29
|
+
read polymorphic belongs to | 24.57 ms | 0.0 MB |
|
30
|
+
write polymorphic belongs to | 75.65 ms | 0.02 MB |
|
31
|
+
reflect_on_all_associations | 200.93 ms | 62.18 MB |
|
32
|
+
association | 5.24 ms | 0.0 MB |
|
33
|
+
Persistence
|
34
|
+
save! | 443.02 ms | 7.63 MB |
|
35
|
+
destroy | 17.28 ms | 0.04 MB |
|
36
|
+
valid? and errors | 142.18 ms | 0.0 MB |
|
37
|
+
Total | 8.38 s | 514.16 MB |
|
@@ -0,0 +1,44 @@
|
|
1
|
+
MR::Model
|
2
|
+
---------
|
3
|
+
Configuration
|
4
|
+
record_class read | 6.2 ms | 0.0 MB |
|
5
|
+
record_class write | 16.31 ms | 0.0 MB |
|
6
|
+
Initialization
|
7
|
+
initialize with no arguments | 328.62 ms | 38.23 MB |
|
8
|
+
initialize with a record | 29.01 ms | 0.73 MB |
|
9
|
+
initialize with a hash | 900.97 ms | 59.46 MB |
|
10
|
+
initialize with a record and hash | 451.5 ms | 1.08 MB |
|
11
|
+
Comparison
|
12
|
+
== unequal | 58.81 ms | 0.0 MB |
|
13
|
+
== equal | 59.7 ms | 0.0 MB |
|
14
|
+
Fields
|
15
|
+
field_reader | 430.61 ms | 169.25 MB |
|
16
|
+
field_writer | 263.24 ms | 65.88 MB |
|
17
|
+
field_accessor | 672.82 ms | 250.2 MB |
|
18
|
+
read single field | 25.72 ms | 0.0 MB |
|
19
|
+
write single field | 123.32 ms | 2.1 MB |
|
20
|
+
read single field was | 35.86 ms | 0.31 MB |
|
21
|
+
single field changed | 37.95 ms | 0.0 MB |
|
22
|
+
fields | 278.65 ms | 21.94 MB |
|
23
|
+
fields= | 415.15 ms | 2.04 MB |
|
24
|
+
Associations
|
25
|
+
belongs_to | 304.7 ms | 121.5 MB |
|
26
|
+
has_many | 324.99 ms | 1.86 MB |
|
27
|
+
has_one | 334.34 ms | 0.0 MB |
|
28
|
+
polymorphic_belongs_to | 315.62 ms | 1.72 MB |
|
29
|
+
read belongs to | 198.68 ms | 0.0 MB |
|
30
|
+
write belongs to | 482.21 ms | 0.0 MB |
|
31
|
+
read has many | 218.64 ms | 0.0 MB |
|
32
|
+
write has many | 5884.43 ms | 519.03 MB |
|
33
|
+
read has one | 114.22 ms | 0.79 MB |
|
34
|
+
write has one | 12847.94 ms | 805.3 MB |
|
35
|
+
read polymorphic belongs to | 258.96 ms | 0.0 MB |
|
36
|
+
write polymorphic belongs to | 657.58 ms | 0.04 MB |
|
37
|
+
Persistence
|
38
|
+
save | 8171.23 ms | 206.38 MB |
|
39
|
+
destroy | 3550.59 ms | 0.02 MB |
|
40
|
+
valid? and errors | 6785.77 ms | 0.04 MB |
|
41
|
+
Querying
|
42
|
+
find | 4513.17 ms | 0.0 MB |
|
43
|
+
all | 3885.71 ms | 0.0 MB |
|
44
|
+
Total | 83.28 s | 1007.97 MB |
|
@@ -0,0 +1,46 @@
|
|
1
|
+
MR::ReadModel
|
2
|
+
-------------
|
3
|
+
Fields
|
4
|
+
field | 189.57 ms | 81.12 MB |
|
5
|
+
field with select args | 258.46 ms | 61.79 MB |
|
6
|
+
field with select block | 393.61 ms | 177.38 MB |
|
7
|
+
typecast string | 46.82 ms | 2.3 MB |
|
8
|
+
typecast text | 54.24 ms | 0.72 MB |
|
9
|
+
typecast binary | 39.91 ms | 0.29 MB |
|
10
|
+
typecast integer | 51.2 ms | 0.0 MB |
|
11
|
+
typecast primary key | 54.25 ms | 0.0 MB |
|
12
|
+
typecast float | 48.58 ms | 0.0 MB |
|
13
|
+
typecast decimal | 63.79 ms | 0.9 MB |
|
14
|
+
typecast datetime | 222.36 ms | 0.0 MB |
|
15
|
+
typecast timestamp | 224.93 ms | 0.0 MB |
|
16
|
+
typecast time | 225.3 ms | 0.0 MB |
|
17
|
+
typecast date | 281.33 ms | 0.0 MB |
|
18
|
+
typecast boolean | 67.83 ms | 0.0 MB |
|
19
|
+
Querying
|
20
|
+
select | 49.15 ms | 0.0 MB |
|
21
|
+
select with block | 65.79 ms | 0.16 MB |
|
22
|
+
from | 10.56 ms | 0.0 MB |
|
23
|
+
joins | 48.56 ms | 0.08 MB |
|
24
|
+
joins with block | 67.98 ms | -0.16 MB |
|
25
|
+
where | 81.42 ms | 0.07 MB |
|
26
|
+
where with block | 80.65 ms | 0.07 MB |
|
27
|
+
order | 78.45 ms | 0.07 MB |
|
28
|
+
order with block | 90.07 ms | 0.07 MB |
|
29
|
+
group | 53.91 ms | 0.07 MB |
|
30
|
+
group with block | 93.91 ms | 0.07 MB |
|
31
|
+
having | 76.13 ms | -0.75 MB |
|
32
|
+
having with block | 79.41 ms | 0.08 MB |
|
33
|
+
limit | 49.43 ms | 0.07 MB |
|
34
|
+
limit with block | 80.49 ms | 0.07 MB |
|
35
|
+
offset | 68.07 ms | 0.07 MB |
|
36
|
+
offset with block | 73.57 ms | -1.16 MB |
|
37
|
+
merge | 369.98 ms | 0.08 MB |
|
38
|
+
merge with block | 103.48 ms | 0.07 MB |
|
39
|
+
inner join subquery | 77.23 ms | 24.49 MB |
|
40
|
+
left outer join subquery | 76.27 ms | 24.32 MB |
|
41
|
+
right outer join subquery | 83.2 ms | 24.64 MB |
|
42
|
+
full outer join subquery | 70.24 ms | 23.23 MB |
|
43
|
+
find | 6798.8 ms | 833.29 MB |
|
44
|
+
query | 6976.37 ms | 404.91 MB |
|
45
|
+
subquery query | 14832.29 ms | 1193.85 MB |
|
46
|
+
Total | 43.85 s | 1071.88 MB |
|
data/bench/setup.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
$LOAD_PATH.push File.expand_path('../..', __FILE__)
|
2
|
+
require 'test/support/setup_test_db'
|
3
|
+
require 'mr'
|
4
|
+
require 'whysoslow'
|
5
|
+
|
6
|
+
require 'test/support/models/area'
|
7
|
+
require 'test/support/models/comment'
|
8
|
+
require 'test/support/models/image'
|
9
|
+
require 'test/support/models/user'
|
10
|
+
require 'test/support/read_models/subquery_data'
|
11
|
+
require 'test/support/read_models/user_with_area_data'
|
12
|
+
|
13
|
+
module Bench
|
14
|
+
|
15
|
+
class Profiler
|
16
|
+
|
17
|
+
def initialize(file_path)
|
18
|
+
@logger = Logger.new(file_path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def run(title, &block)
|
22
|
+
printer = Printer.new(@logger, title)
|
23
|
+
Whysoslow::Runner.new(printer, :time_unit => 's').run do
|
24
|
+
self.instance_eval(&block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def section(title, &block)
|
29
|
+
@logger.puts(title)
|
30
|
+
ActiveRecord::Base.transaction do
|
31
|
+
yield
|
32
|
+
raise ActiveRecord::Rollback
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def benchmark(message, times = 10000, options = nil, &block)
|
37
|
+
GC.disable
|
38
|
+
iterations = [*0..(times - 1)]
|
39
|
+
printer = BenchmarkPrinter.new(@logger, message)
|
40
|
+
Whysoslow::Runner.new(printer, options || {}).run{ iterations.each(&block) }
|
41
|
+
GC.enable
|
42
|
+
GC.start
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
class BasePrinter
|
48
|
+
|
49
|
+
def initialize(logger, title)
|
50
|
+
@logger = logger
|
51
|
+
@title = title
|
52
|
+
@logger.sync = true
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def output_columns(*columns)
|
58
|
+
@logger.puts "#{columns.join(" | ")} |"
|
59
|
+
end
|
60
|
+
|
61
|
+
def message(string)
|
62
|
+
string.ljust(40)
|
63
|
+
end
|
64
|
+
|
65
|
+
def time_taken(results)
|
66
|
+
measurement = results.measurements.find{ |(type, time)| type == :real }
|
67
|
+
time_taken = RoundedNumber.new(measurement.last).to_s.rjust(10)
|
68
|
+
unit = results.measurement_units.to_s.ljust(2)
|
69
|
+
"#{time_taken} #{unit}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def memory_diff(results)
|
73
|
+
memory = results.snapshots.map(&:memory)
|
74
|
+
memory_diff = RoundedNumber.new(memory.last - memory.first).to_s.rjust(10)
|
75
|
+
unit = results.snapshot_units.to_s.ljust(2)
|
76
|
+
"#{memory_diff} #{unit}"
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
class Printer < BasePrinter
|
82
|
+
|
83
|
+
def print(thing)
|
84
|
+
case thing
|
85
|
+
when :title
|
86
|
+
@logger.puts(@title)
|
87
|
+
@logger.puts('-' * @title.size)
|
88
|
+
when Whysoslow::Results
|
89
|
+
output_columns message("Total"),
|
90
|
+
time_taken(thing),
|
91
|
+
memory_diff(thing)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
class BenchmarkPrinter < BasePrinter
|
98
|
+
|
99
|
+
def print(thing)
|
100
|
+
case thing
|
101
|
+
when Whysoslow::Results
|
102
|
+
output_columns message(" #{@title}"),
|
103
|
+
time_taken(thing),
|
104
|
+
memory_diff(thing)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
class Logger
|
111
|
+
|
112
|
+
def initialize(file_path)
|
113
|
+
@file = File.open(file_path, 'w')
|
114
|
+
@ios = [ @file, $stdout ]
|
115
|
+
end
|
116
|
+
|
117
|
+
def method_missing(method, *args, &block)
|
118
|
+
@ios.each{ |io| io.send(method, *args, &block) }
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
module RoundedNumber
|
124
|
+
ROUND_PRECISION = 2
|
125
|
+
ROUND_MODIFIER = 10 ** ROUND_PRECISION
|
126
|
+
|
127
|
+
def self.new(number)
|
128
|
+
rounded_number = (number * ROUND_MODIFIER).to_i / ROUND_MODIFIER.to_f
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|