nativepluck 0.1.2 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f1725dab8cb0df803da1644c6b1f3c7121b07dda79db810812ead5dc6227c66
4
- data.tar.gz: 5008c672d4879c021ff12b7cf3620f73b07fb4b72639119032e808a9db2408a1
3
+ metadata.gz: 822f0736577b8f743c12e6c9898aa4013743be9ce14c1266b41b9cb43558f168
4
+ data.tar.gz: fa6c300fe197c60bbdd065b61bd46f1226880c93b22a5b60d1068ba50e888382
5
5
  SHA512:
6
- metadata.gz: 4315946fbd46106929b767b97878334c302ae71c5eaa37d99f28f1aa3c84e88cb98f65fafd4d3f01dec8363efa36933d05b793b67921ab386f3fd070b42bf5c9
7
- data.tar.gz: 870b97217c6f66684862e9d5b197f44c1856e8a640af462d324b71a25e184eb150c1a8d26b5123bbe663ad99a81bc71c9f9a2a787a4df0681c57b865331d6424
6
+ metadata.gz: 6d4608bee883ced109deece5cfc39208582c1ae228a6b3ed7fac9bb941d3bcdfa8e7b3ab89aa78d3745fe5b1b08a9d07b70b111c61212e3009f801496e7e3ac2
7
+ data.tar.gz: d5f6bca37ab789d4e434041ff7349854d8f12fface99bb013e554b5061904155f1196bd363e18b0598b43cf7b0fd3caec1cf2f7ef99735e259f67f98cead94d6
data/README.md CHANGED
@@ -22,499 +22,39 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- * If you want to use `nativepluck` as an `ActiveRecord` method, add `include Nativepluck` inside your model.<br>
26
- In this usage mode (more examples in `test/dummy/test/models/genericmodel_test.rb`):
27
- `<Model>.nativepluck(:id, order: {id: :asc} , limit: limit)`<br>
28
- Internally, the method call will generate a SQL query based on your arguments and use native PostgreSQL typecasting on the query results.
29
-
30
- * If you have more complex queries that the above mixin method doesn't currently support (such as `joins`):<br>
31
- You can take an existing ActiveRecord query method call chain, for example:<br>
25
+ * You can use `nativepluck` just like you use `pluck` , as in `<Model>.limit(10).nativepluck(:id,:name)`<br>
26
+ * You can also set in your `config/initializers/nativepluck.rb` , `Nativepluck.set_override_pluck true` and we'll override `pluck` with `nativepluck`<br>
27
+ No changes needed on your side, completely transparent<br>
28
+
29
+ * You can take an existing ActiveRecord query method call chain, for example:<br>
32
30
  `<Model>.where('id >= 21').limit(100).joins(:some_association_to_another_model).pluck(:id)`<br>
33
- Change the `pluck` call to `select` and use it as the argument to the `nativepluck` module method: `Nativepluck.nativepluck(<Model>.where('id >= 21').limit(100).joins(:some_association_to_another_model).select(:id))`<br>
31
+ Change the `pluck` call to `select` and use it as the argument to the `nativepluck` module method:<br>
32
+ `Nativepluck.nativepluck(<Model>.where('id >= 21').limit(100).joins(:some_association_to_another_model).select(:id))`<br>
34
33
  Internally, this method calls `to_sql` on the supplied `ActiveRecord::Relation` instance and submits the generated SQL query to the database. Again, native PostgreSQL typecasting is performed on the query results.<br>
34
+
35
35
  * You can also use a raw SQL string argument in the module method, e.g.,<br>
36
36
  `Nativepluck.nativepluck('SELECT models.id FROM models JOIN some_other_models ON some_other_models.model_id = models.id WHERE models.id > 21 LIMIT 100')`.
37
37
 
38
+ ## Benchmarks
39
+
40
+ Due to GitLab not rendering CSV properly we also host the CSV results at [GitHub](https://github.com/ohaddahan/csv_depo/tree/master)<br>
41
+
38
42
  ## Memory Benchmarks
39
43
 
40
44
  To run the benchmarks use:
41
45
  `BenchMarks::Memory::benchmark(write_to_file: true|false, row_limit: nil|integer)`<br>
42
46
 
43
- ### Memory allocation benchmark
47
+ * We're seeing up to ~50X less object allocations for integer columns<br>
44
48
 
45
- Method | Attribute Name | Total Allocated | Total Retained
46
- -------|-----------------|------------------|-----------------
47
- pluck | id | 5125 | 3
48
- nativepluck | id | 20 | 1
49
- nativepluck_raw_to_sql | id | 68 | 5
50
- nativepluck_raw_string | id | 7 | 1
51
- pluck | integer_col | 5125 | 3
52
- nativepluck | integer_col | 20 | 1
53
- nativepluck_raw_to_sql | integer_col | 68 | 5
54
- nativepluck_raw_string | integer_col | 7 | 1
55
- pluck | string_col | 7125 | 1003
56
- nativepluck | string_col | 1020 | 1001
57
- nativepluck_raw_to_sql | string_col | 1068 | 1005
58
- nativepluck_raw_string | string_col | 1007 | 1001
59
- pluck | datetime_col | 22125 | 2003
60
- nativepluck | datetime_col | 1020 | 1001
61
- nativepluck_raw_to_sql | datetime_col | 1068 | 1005
62
- nativepluck_raw_string | datetime_col | 1007 | 1001
63
- pluck | float_col | 5125 | 3
64
- nativepluck | float_col | 20 | 1
65
- nativepluck_raw_to_sql | float_col | 68 | 5
66
- nativepluck_raw_string | float_col | 7 | 1
67
- pluck | json_col | 16125 | 3003
68
- nativepluck | json_col | 11020 | 3001
69
- nativepluck_raw_to_sql | json_col | 11068 | 3005
70
- nativepluck_raw_string | json_col | 11007 | 3001
71
- pluck | jsonb_col | 16125 | 3003
72
- nativepluck | jsonb_col | 11020 | 3001
73
- nativepluck_raw_to_sql | jsonb_col | 11068 | 3005
74
- nativepluck_raw_string | jsonb_col | 11007 | 3001
75
- pluck | created_at | 22125 | 2003
76
- nativepluck | created_at | 1020 | 1001
77
- nativepluck_raw_to_sql | created_at | 1068 | 1005
78
- nativepluck_raw_string | created_at | 1007 | 1001
79
- pluck | updated_at | 22125 | 2003
80
- nativepluck | updated_at | 1020 | 1001
81
- nativepluck_raw_to_sql | updated_at | 1068 | 1005
82
- nativepluck_raw_string | updated_at | 1007 | 1001
83
-
84
- ### Allocated Memory by Class Benchmark
85
-
86
- Class| Attribute Name| pluck| nativepluck| nativepluck_raw_to_sql| nativepluck_raw_string
87
- -----|---------------|------|------------|-----------------------|-----------------------
88
- Array| id|218568|8280|9680|8200
89
- Array| integer_col|218568|8280|9680|8200
90
- Array| string_col|218568|8280|9680|8200
91
- Array| datetime_col|298568|8280|9680|8200
92
- Array| float_col|218568|8280|9680|8200
93
- Array| json_col|218568|8280|9680|8200
94
- Array| jsonb_col|218568|8280|9680|8200
95
- Array| created_at|298568|8280|9680|8200
96
- Array| updated_at|298568|8280|9680|8200
97
- PG::Result| id|30976|30976|30976|30976
98
- PG::Result| integer_col|30976|30976|30976|30976
99
- PG::Result| string_col|39168|39168|39168|39168
100
- PG::Result| datetime_col|51456|51456|51456|51456
101
- PG::Result| float_col|43264|43264|43264|43264
102
- PG::Result| json_col|131328|131328|131328|131328
103
- PG::Result| jsonb_col|139520|139520|139520|139520
104
- PG::Result| created_at|51456|51456|51456|51456
105
- PG::Result| updated_at|51456|51456|51456|51456
106
- String| id|2258|576|256|0
107
- String| integer_col|2306|576|304|0
108
- String| string_col|82306|40576|40304|40000
109
- String| datetime_col|389175|576|304|0
110
- String| float_col|2306|576|304|0
111
- String| json_col|418356|416626|416354|416050
112
- String| jsonb_col|425356|423626|423354|423050
113
- String| created_at|387306|576|304|0
114
- String| updated_at|387306|576|304|0
115
- Hash| id|1696|576|544|0
116
- Hash| integer_col|1696|576|544|0
117
- Hash| string_col|1696|576|544|0
118
- Hash| datetime_col|1696|576|544|0
119
- Hash| float_col|1696|576|544|0
120
- Hash| json_col|577696|576576|576544|576000
121
- Hash| jsonb_col|577696|576576|576544|576000
122
- Hash| created_at|1696|576|544|0
123
- Hash| updated_at|1696|576|544|0
124
- ActiveRecord::Relation| id|352|0|352|0
125
- ActiveRecord::Relation| integer_col|352|0|352|0
126
- ActiveRecord::Relation| string_col|352|0|352|0
127
- ActiveRecord::Relation| datetime_col|352|0|352|0
128
- ActiveRecord::Relation| float_col|352|0|352|0
129
- ActiveRecord::Relation| json_col|352|0|352|0
130
- ActiveRecord::Relation| jsonb_col|352|0|352|0
131
- ActiveRecord::Relation| created_at|352|0|352|0
132
- ActiveRecord::Relation| updated_at|352|0|352|0
133
- MatchData| id|280|0|0|0
134
- MatchData| integer_col|280|0|0|0
135
- MatchData| string_col|280|0|0|0
136
- MatchData| datetime_col|280280|0|0|0
137
- MatchData| float_col|280|0|0|0
138
- MatchData| json_col|280|0|0|0
139
- MatchData| jsonb_col|280|0|0|0
140
- MatchData| created_at|280280|0|0|0
141
- MatchData| updated_at|280280|0|0|0
142
- Time| id|258|0|0|0
143
- Time| integer_col|258|0|0|0
144
- Time| string_col|258|0|0|0
145
- Time| datetime_col|244258|86000|86000|86000
146
- Time| float_col|258|0|0|0
147
- Time| json_col|258|0|0|0
148
- Time| jsonb_col|258|0|0|0
149
- Time| created_at|244258|86000|86000|86000
150
- Time| updated_at|244258|86000|86000|86000
151
- Arel::Nodes::SelectCore| id|104|0|104|0
152
- Arel::Nodes::SelectCore| integer_col|104|0|104|0
153
- Arel::Nodes::SelectCore| string_col|104|0|104|0
154
- Arel::Nodes::SelectCore| datetime_col|104|0|104|0
155
- Arel::Nodes::SelectCore| float_col|104|0|104|0
156
- Arel::Nodes::SelectCore| json_col|104|0|104|0
157
- Arel::Nodes::SelectCore| jsonb_col|104|0|104|0
158
- Arel::Nodes::SelectCore| created_at|104|0|104|0
159
- Arel::Nodes::SelectCore| updated_at|104|0|104|0
160
- ActiveSupport::Notifications::Event| id|96|0|0|0
161
- ActiveSupport::Notifications::Event| integer_col|96|0|0|0
162
- ActiveSupport::Notifications::Event| string_col|96|0|0|0
163
- ActiveSupport::Notifications::Event| datetime_col|96|0|0|0
164
- ActiveSupport::Notifications::Event| float_col|96|0|0|0
165
- ActiveSupport::Notifications::Event| json_col|96|0|0|0
166
- ActiveSupport::Notifications::Event| jsonb_col|96|0|0|0
167
- ActiveSupport::Notifications::Event| created_at|96|0|0|0
168
- ActiveSupport::Notifications::Event| updated_at|96|0|0|0
169
- Arel::Nodes::SelectStatement| id|88|0|88|0
170
- Arel::Nodes::SelectStatement| integer_col|88|0|88|0
171
- Arel::Nodes::SelectStatement| string_col|88|0|88|0
172
- Arel::Nodes::SelectStatement| datetime_col|88|0|88|0
173
- Arel::Nodes::SelectStatement| float_col|88|0|88|0
174
- Arel::Nodes::SelectStatement| json_col|88|0|88|0
175
- Arel::Nodes::SelectStatement| jsonb_col|88|0|88|0
176
- Arel::Nodes::SelectStatement| created_at|88|0|88|0
177
- Arel::Nodes::SelectStatement| updated_at|88|0|88|0
178
- ActiveModel::Attribute::WithCastValue| id|80|0|80|0
179
- ActiveModel::Attribute::WithCastValue| integer_col|80|0|80|0
180
- ActiveModel::Attribute::WithCastValue| string_col|80|0|80|0
181
- ActiveModel::Attribute::WithCastValue| datetime_col|80|0|80|0
182
- ActiveModel::Attribute::WithCastValue| float_col|80|0|80|0
183
- ActiveModel::Attribute::WithCastValue| json_col|80|0|80|0
184
- ActiveModel::Attribute::WithCastValue| jsonb_col|80|0|80|0
185
- ActiveModel::Attribute::WithCastValue| created_at|80|0|80|0
186
- ActiveModel::Attribute::WithCastValue| updated_at|80|0|80|0
187
- ActiveRecord::Result| id|72|0|0|0
188
- ActiveRecord::Result| integer_col|72|0|0|0
189
- ActiveRecord::Result| string_col|72|0|0|0
190
- ActiveRecord::Result| datetime_col|72|0|0|0
191
- ActiveRecord::Result| float_col|72|0|0|0
192
- ActiveRecord::Result| json_col|72|0|0|0
193
- ActiveRecord::Result| jsonb_col|72|0|0|0
194
- ActiveRecord::Result| created_at|72|0|0|0
195
- ActiveRecord::Result| updated_at|72|0|0|0
196
- Arel::Attributes::Attribute| id|40|0|40|0
197
- Arel::Attributes::Attribute| integer_col|40|0|40|0
198
- Arel::Attributes::Attribute| string_col|40|0|40|0
199
- Arel::Attributes::Attribute| datetime_col|40|0|40|0
200
- Arel::Attributes::Attribute| float_col|40|0|40|0
201
- Arel::Attributes::Attribute| json_col|40|0|40|0
202
- Arel::Attributes::Attribute| jsonb_col|40|0|40|0
203
- Arel::Attributes::Attribute| created_at|40|0|40|0
204
- Arel::Attributes::Attribute| updated_at|40|0|40|0
205
- Arel::Collectors::Bind| id|40|0|0|0
206
- Arel::Collectors::Bind| integer_col|40|0|0|0
207
- Arel::Collectors::Bind| string_col|40|0|0|0
208
- Arel::Collectors::Bind| datetime_col|40|0|0|0
209
- Arel::Collectors::Bind| float_col|40|0|0|0
210
- Arel::Collectors::Bind| json_col|40|0|0|0
211
- Arel::Collectors::Bind| jsonb_col|40|0|0|0
212
- Arel::Collectors::Bind| created_at|40|0|0|0
213
- Arel::Collectors::Bind| updated_at|40|0|0|0
214
- Arel::Collectors::Composite| id|40|0|0|0
215
- Arel::Collectors::Composite| integer_col|40|0|0|0
216
- Arel::Collectors::Composite| string_col|40|0|0|0
217
- Arel::Collectors::Composite| datetime_col|40|0|0|0
218
- Arel::Collectors::Composite| float_col|40|0|0|0
219
- Arel::Collectors::Composite| json_col|40|0|0|0
220
- Arel::Collectors::Composite| jsonb_col|40|0|0|0
221
- Arel::Collectors::Composite| created_at|40|0|0|0
222
- Arel::Collectors::Composite| updated_at|40|0|0|0
223
- Arel::Collectors::SQLString| id|40|0|40|0
224
- Arel::Collectors::SQLString| integer_col|40|0|40|0
225
- Arel::Collectors::SQLString| string_col|40|0|40|0
226
- Arel::Collectors::SQLString| datetime_col|40|0|40|0
227
- Arel::Collectors::SQLString| float_col|40|0|40|0
228
- Arel::Collectors::SQLString| json_col|40|0|40|0
229
- Arel::Collectors::SQLString| jsonb_col|40|0|40|0
230
- Arel::Collectors::SQLString| created_at|40|0|40|0
231
- Arel::Collectors::SQLString| updated_at|40|0|40|0
232
- Arel::Nodes::BindParam| id|40|0|40|0
233
- Arel::Nodes::BindParam| integer_col|40|0|40|0
234
- Arel::Nodes::BindParam| string_col|40|0|40|0
235
- Arel::Nodes::BindParam| datetime_col|40|0|40|0
236
- Arel::Nodes::BindParam| float_col|40|0|40|0
237
- Arel::Nodes::BindParam| json_col|40|0|40|0
238
- Arel::Nodes::BindParam| jsonb_col|40|0|40|0
239
- Arel::Nodes::BindParam| created_at|40|0|40|0
240
- Arel::Nodes::BindParam| updated_at|40|0|40|0
241
- Arel::Nodes::JoinSource| id|40|0|40|0
242
- Arel::Nodes::JoinSource| integer_col|40|0|40|0
243
- Arel::Nodes::JoinSource| string_col|40|0|40|0
244
- Arel::Nodes::JoinSource| datetime_col|40|0|40|0
245
- Arel::Nodes::JoinSource| float_col|40|0|40|0
246
- Arel::Nodes::JoinSource| json_col|40|0|40|0
247
- Arel::Nodes::JoinSource| jsonb_col|40|0|40|0
248
- Arel::Nodes::JoinSource| created_at|40|0|40|0
249
- Arel::Nodes::JoinSource| updated_at|40|0|40|0
250
- Arel::Nodes::Limit| id|40|0|40|0
251
- Arel::Nodes::Limit| integer_col|40|0|40|0
252
- Arel::Nodes::Limit| string_col|40|0|40|0
253
- Arel::Nodes::Limit| datetime_col|40|0|40|0
254
- Arel::Nodes::Limit| float_col|40|0|40|0
255
- Arel::Nodes::Limit| json_col|40|0|40|0
256
- Arel::Nodes::Limit| jsonb_col|40|0|40|0
257
- Arel::Nodes::Limit| created_at|40|0|40|0
258
- Arel::Nodes::Limit| updated_at|40|0|40|0
259
- Arel::Nodes::Top| id|40|0|40|0
260
- Arel::Nodes::Top| integer_col|40|0|40|0
261
- Arel::Nodes::Top| string_col|40|0|40|0
262
- Arel::Nodes::Top| datetime_col|40|0|40|0
263
- Arel::Nodes::Top| float_col|40|0|40|0
264
- Arel::Nodes::Top| json_col|40|0|40|0
265
- Arel::Nodes::Top| jsonb_col|40|0|40|0
266
- Arel::Nodes::Top| created_at|40|0|40|0
267
- Arel::Nodes::Top| updated_at|40|0|40|0
268
- Arel::SelectManager| id|40|0|40|0
269
- Arel::SelectManager| integer_col|40|0|40|0
270
- Arel::SelectManager| string_col|40|0|40|0
271
- Arel::SelectManager| datetime_col|40|0|40|0
272
- Arel::SelectManager| float_col|40|0|40|0
273
- Arel::SelectManager| json_col|40|0|40|0
274
- Arel::SelectManager| jsonb_col|40|0|40|0
275
- Arel::SelectManager| created_at|40|0|40|0
276
- Arel::SelectManager| updated_at|40|0|40|0
277
- PG::TypeMapByColumn| id|40|40|40|40
278
- PG::TypeMapByColumn| integer_col|40|40|40|40
279
- PG::TypeMapByColumn| string_col|40|40|40|40
280
- PG::TypeMapByColumn| datetime_col|40|40|40|40
281
- PG::TypeMapByColumn| float_col|40|40|40|40
282
- PG::TypeMapByColumn| json_col|40|40|40|40
283
- PG::TypeMapByColumn| jsonb_col|40|40|40|40
284
- PG::TypeMapByColumn| created_at|40|40|40|40
285
- PG::TypeMapByColumn| updated_at|40|40|40|40
286
- Rational| datetime_col|80000|0|0|0
287
- Rational| created_at|80000|0|0|0
288
- Rational| updated_at|80000|0|0|0
289
- JSON::Ext::Parser| json_col|1168000|1168000|1168000|1168000
290
- JSON::Ext::Parser| jsonb_col|1168000|1168000|1168000|1168000
291
- Arel::Collectors::SubstituteBinds| id|0|0|40|0
292
- Arel::Collectors::SubstituteBinds| integer_col|0|0|40|0
293
- Arel::Collectors::SubstituteBinds| string_col|0|0|40|0
294
- Arel::Collectors::SubstituteBinds| datetime_col|0|0|40|0
295
- Arel::Collectors::SubstituteBinds| float_col|0|0|40|0
296
- Arel::Collectors::SubstituteBinds| json_col|0|0|40|0
297
- Arel::Collectors::SubstituteBinds| jsonb_col|0|0|40|0
298
- Arel::Collectors::SubstituteBinds| created_at|0|0|40|0
299
- Arel::Collectors::SubstituteBinds| updated_at|0|0|40|0
49
+ ### Memory allocation benchmark
50
+ * Benchmark code `test/dummy/test/benchmarks/memory_benchmarks.rb`
51
+ * Benchmark CSV `test/dummy/memory_report.csv`
300
52
 
301
53
  ### Allocated Objects by Class Benchmark
302
54
 
303
- Class| Attribute Name| pluck| nativepluck| nativepluck_raw_to_sql| nativepluck_raw_string
304
- -----|---------------|------|------------|-----------------------|-----------------------
305
- Array| id|5063|7|42|5
306
- Array| integer_col|5063|7|42|5
307
- Array| string_col|5063|7|42|5
308
- Array| datetime_col|7063|7|42|5
309
- Array| float_col|5063|7|42|5
310
- Array| json_col|5063|7|42|5
311
- Array| jsonb_col|5063|7|42|5
312
- Array| created_at|7063|7|42|5
313
- Array| updated_at|7063|7|42|5
314
- String| id|28|8|4|0
315
- String| integer_col|28|8|4|0
316
- String| string_col|2028|1008|1004|1000
317
- String| datetime_col|9028|8|4|0
318
- String| float_col|28|8|4|0
319
- String| json_col|7028|7008|7004|7000
320
- String| jsonb_col|7028|7008|7004|7000
321
- String| created_at|9028|8|4|0
322
- String| updated_at|9028|8|4|0
323
- Hash| id|11|3|6|0
324
- Hash| integer_col|11|3|6|0
325
- Hash| string_col|11|3|6|0
326
- Hash| datetime_col|11|3|6|0
327
- Hash| float_col|11|3|6|0
328
- Hash| json_col|3011|3003|3006|3000
329
- Hash| jsonb_col|3011|3003|3006|3000
330
- Hash| created_at|11|3|6|0
331
- Hash| updated_at|11|3|6|0
332
- ActiveRecord::Relation| id|3|0|3|0
333
- ActiveRecord::Relation| integer_col|3|0|3|0
334
- ActiveRecord::Relation| string_col|3|0|3|0
335
- ActiveRecord::Relation| datetime_col|3|0|3|0
336
- ActiveRecord::Relation| float_col|3|0|3|0
337
- ActiveRecord::Relation| json_col|3|0|3|0
338
- ActiveRecord::Relation| jsonb_col|3|0|3|0
339
- ActiveRecord::Relation| created_at|3|0|3|0
340
- ActiveRecord::Relation| updated_at|3|0|3|0
341
- Time| id|3|0|0|0
342
- Time| integer_col|3|0|0|0
343
- Time| string_col|3|0|0|0
344
- Time| datetime_col|3003|1000|1000|1000
345
- Time| float_col|3|0|0|0
346
- Time| json_col|3|0|0|0
347
- Time| jsonb_col|3|0|0|0
348
- Time| created_at|3003|1000|1000|1000
349
- Time| updated_at|3003|1000|1000|1000
350
- ActiveModel::Attribute::WithCastValue| id|1|0|1|0
351
- ActiveModel::Attribute::WithCastValue| integer_col|1|0|1|0
352
- ActiveModel::Attribute::WithCastValue| string_col|1|0|1|0
353
- ActiveModel::Attribute::WithCastValue| datetime_col|1|0|1|0
354
- ActiveModel::Attribute::WithCastValue| float_col|1|0|1|0
355
- ActiveModel::Attribute::WithCastValue| json_col|1|0|1|0
356
- ActiveModel::Attribute::WithCastValue| jsonb_col|1|0|1|0
357
- ActiveModel::Attribute::WithCastValue| created_at|1|0|1|0
358
- ActiveModel::Attribute::WithCastValue| updated_at|1|0|1|0
359
- ActiveRecord::Result| id|1|0|0|0
360
- ActiveRecord::Result| integer_col|1|0|0|0
361
- ActiveRecord::Result| string_col|1|0|0|0
362
- ActiveRecord::Result| datetime_col|1|0|0|0
363
- ActiveRecord::Result| float_col|1|0|0|0
364
- ActiveRecord::Result| json_col|1|0|0|0
365
- ActiveRecord::Result| jsonb_col|1|0|0|0
366
- ActiveRecord::Result| created_at|1|0|0|0
367
- ActiveRecord::Result| updated_at|1|0|0|0
368
- ActiveSupport::Notifications::Event| id|1|0|0|0
369
- ActiveSupport::Notifications::Event| integer_col|1|0|0|0
370
- ActiveSupport::Notifications::Event| string_col|1|0|0|0
371
- ActiveSupport::Notifications::Event| datetime_col|1|0|0|0
372
- ActiveSupport::Notifications::Event| float_col|1|0|0|0
373
- ActiveSupport::Notifications::Event| json_col|1|0|0|0
374
- ActiveSupport::Notifications::Event| jsonb_col|1|0|0|0
375
- ActiveSupport::Notifications::Event| created_at|1|0|0|0
376
- ActiveSupport::Notifications::Event| updated_at|1|0|0|0
377
- Arel::Attributes::Attribute| id|1|0|1|0
378
- Arel::Attributes::Attribute| integer_col|1|0|1|0
379
- Arel::Attributes::Attribute| string_col|1|0|1|0
380
- Arel::Attributes::Attribute| datetime_col|1|0|1|0
381
- Arel::Attributes::Attribute| float_col|1|0|1|0
382
- Arel::Attributes::Attribute| json_col|1|0|1|0
383
- Arel::Attributes::Attribute| jsonb_col|1|0|1|0
384
- Arel::Attributes::Attribute| created_at|1|0|1|0
385
- Arel::Attributes::Attribute| updated_at|1|0|1|0
386
- Arel::Collectors::Bind| id|1|0|0|0
387
- Arel::Collectors::Bind| integer_col|1|0|0|0
388
- Arel::Collectors::Bind| string_col|1|0|0|0
389
- Arel::Collectors::Bind| datetime_col|1|0|0|0
390
- Arel::Collectors::Bind| float_col|1|0|0|0
391
- Arel::Collectors::Bind| json_col|1|0|0|0
392
- Arel::Collectors::Bind| jsonb_col|1|0|0|0
393
- Arel::Collectors::Bind| created_at|1|0|0|0
394
- Arel::Collectors::Bind| updated_at|1|0|0|0
395
- Arel::Collectors::Composite| id|1|0|0|0
396
- Arel::Collectors::Composite| integer_col|1|0|0|0
397
- Arel::Collectors::Composite| string_col|1|0|0|0
398
- Arel::Collectors::Composite| datetime_col|1|0|0|0
399
- Arel::Collectors::Composite| float_col|1|0|0|0
400
- Arel::Collectors::Composite| json_col|1|0|0|0
401
- Arel::Collectors::Composite| jsonb_col|1|0|0|0
402
- Arel::Collectors::Composite| created_at|1|0|0|0
403
- Arel::Collectors::Composite| updated_at|1|0|0|0
404
- Arel::Collectors::SQLString| id|1|0|1|0
405
- Arel::Collectors::SQLString| integer_col|1|0|1|0
406
- Arel::Collectors::SQLString| string_col|1|0|1|0
407
- Arel::Collectors::SQLString| datetime_col|1|0|1|0
408
- Arel::Collectors::SQLString| float_col|1|0|1|0
409
- Arel::Collectors::SQLString| json_col|1|0|1|0
410
- Arel::Collectors::SQLString| jsonb_col|1|0|1|0
411
- Arel::Collectors::SQLString| created_at|1|0|1|0
412
- Arel::Collectors::SQLString| updated_at|1|0|1|0
413
- Arel::Nodes::BindParam| id|1|0|1|0
414
- Arel::Nodes::BindParam| integer_col|1|0|1|0
415
- Arel::Nodes::BindParam| string_col|1|0|1|0
416
- Arel::Nodes::BindParam| datetime_col|1|0|1|0
417
- Arel::Nodes::BindParam| float_col|1|0|1|0
418
- Arel::Nodes::BindParam| json_col|1|0|1|0
419
- Arel::Nodes::BindParam| jsonb_col|1|0|1|0
420
- Arel::Nodes::BindParam| created_at|1|0|1|0
421
- Arel::Nodes::BindParam| updated_at|1|0|1|0
422
- Arel::Nodes::JoinSource| id|1|0|1|0
423
- Arel::Nodes::JoinSource| integer_col|1|0|1|0
424
- Arel::Nodes::JoinSource| string_col|1|0|1|0
425
- Arel::Nodes::JoinSource| datetime_col|1|0|1|0
426
- Arel::Nodes::JoinSource| float_col|1|0|1|0
427
- Arel::Nodes::JoinSource| json_col|1|0|1|0
428
- Arel::Nodes::JoinSource| jsonb_col|1|0|1|0
429
- Arel::Nodes::JoinSource| created_at|1|0|1|0
430
- Arel::Nodes::JoinSource| updated_at|1|0|1|0
431
- Arel::Nodes::Limit| id|1|0|1|0
432
- Arel::Nodes::Limit| integer_col|1|0|1|0
433
- Arel::Nodes::Limit| string_col|1|0|1|0
434
- Arel::Nodes::Limit| datetime_col|1|0|1|0
435
- Arel::Nodes::Limit| float_col|1|0|1|0
436
- Arel::Nodes::Limit| json_col|1|0|1|0
437
- Arel::Nodes::Limit| jsonb_col|1|0|1|0
438
- Arel::Nodes::Limit| created_at|1|0|1|0
439
- Arel::Nodes::Limit| updated_at|1|0|1|0
440
- Arel::Nodes::SelectCore| id|1|0|1|0
441
- Arel::Nodes::SelectCore| integer_col|1|0|1|0
442
- Arel::Nodes::SelectCore| string_col|1|0|1|0
443
- Arel::Nodes::SelectCore| datetime_col|1|0|1|0
444
- Arel::Nodes::SelectCore| float_col|1|0|1|0
445
- Arel::Nodes::SelectCore| json_col|1|0|1|0
446
- Arel::Nodes::SelectCore| jsonb_col|1|0|1|0
447
- Arel::Nodes::SelectCore| created_at|1|0|1|0
448
- Arel::Nodes::SelectCore| updated_at|1|0|1|0
449
- Arel::Nodes::SelectStatement| id|1|0|1|0
450
- Arel::Nodes::SelectStatement| integer_col|1|0|1|0
451
- Arel::Nodes::SelectStatement| string_col|1|0|1|0
452
- Arel::Nodes::SelectStatement| datetime_col|1|0|1|0
453
- Arel::Nodes::SelectStatement| float_col|1|0|1|0
454
- Arel::Nodes::SelectStatement| json_col|1|0|1|0
455
- Arel::Nodes::SelectStatement| jsonb_col|1|0|1|0
456
- Arel::Nodes::SelectStatement| created_at|1|0|1|0
457
- Arel::Nodes::SelectStatement| updated_at|1|0|1|0
458
- Arel::Nodes::Top| id|1|0|1|0
459
- Arel::Nodes::Top| integer_col|1|0|1|0
460
- Arel::Nodes::Top| string_col|1|0|1|0
461
- Arel::Nodes::Top| datetime_col|1|0|1|0
462
- Arel::Nodes::Top| float_col|1|0|1|0
463
- Arel::Nodes::Top| json_col|1|0|1|0
464
- Arel::Nodes::Top| jsonb_col|1|0|1|0
465
- Arel::Nodes::Top| created_at|1|0|1|0
466
- Arel::Nodes::Top| updated_at|1|0|1|0
467
- Arel::SelectManager| id|1|0|1|0
468
- Arel::SelectManager| integer_col|1|0|1|0
469
- Arel::SelectManager| string_col|1|0|1|0
470
- Arel::SelectManager| datetime_col|1|0|1|0
471
- Arel::SelectManager| float_col|1|0|1|0
472
- Arel::SelectManager| json_col|1|0|1|0
473
- Arel::SelectManager| jsonb_col|1|0|1|0
474
- Arel::SelectManager| created_at|1|0|1|0
475
- Arel::SelectManager| updated_at|1|0|1|0
476
- MatchData| id|1|0|0|0
477
- MatchData| integer_col|1|0|0|0
478
- MatchData| string_col|1|0|0|0
479
- MatchData| datetime_col|1001|0|0|0
480
- MatchData| float_col|1|0|0|0
481
- MatchData| json_col|1|0|0|0
482
- MatchData| jsonb_col|1|0|0|0
483
- MatchData| created_at|1001|0|0|0
484
- MatchData| updated_at|1001|0|0|0
485
- PG::Result| id|1|1|1|1
486
- PG::Result| integer_col|1|1|1|1
487
- PG::Result| string_col|1|1|1|1
488
- PG::Result| datetime_col|1|1|1|1
489
- PG::Result| float_col|1|1|1|1
490
- PG::Result| json_col|1|1|1|1
491
- PG::Result| jsonb_col|1|1|1|1
492
- PG::Result| created_at|1|1|1|1
493
- PG::Result| updated_at|1|1|1|1
494
- PG::TypeMapByColumn| id|1|1|1|1
495
- PG::TypeMapByColumn| integer_col|1|1|1|1
496
- PG::TypeMapByColumn| string_col|1|1|1|1
497
- PG::TypeMapByColumn| datetime_col|1|1|1|1
498
- PG::TypeMapByColumn| float_col|1|1|1|1
499
- PG::TypeMapByColumn| json_col|1|1|1|1
500
- PG::TypeMapByColumn| jsonb_col|1|1|1|1
501
- PG::TypeMapByColumn| created_at|1|1|1|1
502
- PG::TypeMapByColumn| updated_at|1|1|1|1
503
- Rational| datetime_col|2000|0|0|0
504
- Rational| created_at|2000|0|0|0
505
- Rational| updated_at|2000|0|0|0
506
- JSON::Ext::Parser| json_col|1000|1000|1000|1000
507
- JSON::Ext::Parser| jsonb_col|1000|1000|1000|1000
508
- Arel::Collectors::SubstituteBinds| id|0|0|1|0
509
- Arel::Collectors::SubstituteBinds| integer_col|0|0|1|0
510
- Arel::Collectors::SubstituteBinds| string_col|0|0|1|0
511
- Arel::Collectors::SubstituteBinds| datetime_col|0|0|1|0
512
- Arel::Collectors::SubstituteBinds| float_col|0|0|1|0
513
- Arel::Collectors::SubstituteBinds| json_col|0|0|1|0
514
- Arel::Collectors::SubstituteBinds| jsonb_col|0|0|1|0
515
- Arel::Collectors::SubstituteBinds| created_at|0|0|1|0
516
- Arel::Collectors::SubstituteBinds| updated_at|0|0|1|0
517
-
55
+ * Benchmark code `test/dummy/test/benchmarks/memory_benchmarks.rb`
56
+ * Benchmark CSV by objects `test/dummy/by_attributes_objects.csv`
57
+ * Benchmark CSV by memory `test/dummy/by_attributes_memory.csv`
518
58
 
519
59
 
520
60
  ## RunTime Benchmarks
@@ -522,44 +62,10 @@ Arel::Collectors::SubstituteBinds| updated_at|0|0|1|0
522
62
  To run the benchmarks use:
523
63
  `BenchMarks::RunTime::benchmark`<br>
524
64
 
525
- Method | Row Number | Column Name | Results
526
- ------------------|------------|----------------|---------------------------------------------------------------
527
- nativepluck | 1000 | id | 1660.5 i/s
528
- nativepluck_raw SQL_RAW | 1000 | id | 1516.2 i/s - same-ish: difference falls within error
529
- nativepluck_raw :to_sql | 1000 | id | 1139.7 i/s - same-ish: difference falls within error
530
- pluck | 1000 | id | 734.2 i/s - 2.26x slower
531
- nativepluck_raw SQL_RAW | 1000 | integer_col | 1515.4 i/s
532
- nativepluck | 1000 | integer_col | 1388.6 i/s - same-ish: difference falls within error
533
- nativepluck_raw :to_sql | 1000 | integer_col | 1152.5 i/s - same-ish: difference falls within error
534
- pluck | 1000 | integer_col | 594.9 i/s - 2.55x slower
535
- nativepluck | 1000 | string_col | 1317.6 i/s
536
- nativepluck_raw SQL_RAW | 1000 | string_col | 1103.6 i/s - same-ish: difference falls within error
537
- nativepluck_raw :to_sql | 1000 | string_col | 980.7 i/s - same-ish: difference falls within error
538
- pluck | 1000 | string_col | 454.9 i/s - 2.90x slower
539
- nativepluck_raw SQL_RAW | 1000 | datetime_col | 217.4 i/s
540
- nativepluck_raw :to_sql | 1000 | datetime_col | 210.5 i/s - same-ish: difference falls within error
541
- nativepluck | 1000 | datetime_col | 168.6 i/s - same-ish: difference falls within error
542
- pluck | 1000 | datetime_col | 42.6 i/s - 5.10x slower
543
- nativepluck | 1000 | float_col | 666.5 i/s
544
- nativepluck_raw :to_sql | 1000 | float_col | 524.6 i/s - 1.27x slower
545
- nativepluck_raw SQL_RAW | 1000 | float_col | 420.4 i/s - 1.59x slower
546
- pluck | 1000 | float_col | 374.3 i/s - 1.78x slower
547
- nativepluck_raw SQL_RAW | 1000 | json_col | 111.5 i/s
548
- nativepluck | 1000 | json_col | 108.7 i/s - same-ish: difference falls within error
549
- nativepluck_raw :to_sql | 1000 | json_col | 107.0 i/s - same-ish: difference falls within error
550
- pluck | 1000 | json_col | 80.6 i/s - 1.38x slower
551
- nativepluck | 1000 | jsonb_col | 102.8 i/s
552
- nativepluck_raw SQL_RAW | 1000 | jsonb_col | 102.1 i/s - same-ish: difference falls within error
553
- nativepluck_raw :to_sql | 1000 | jsonb_col | 100.0 i/s - same-ish: difference falls within error
554
- pluck | 1000 | jsonb_col | 90.9 i/s - 1.13x slower
555
- nativepluck_raw SQL_RAW | 1000 | created_at | 199.4 i/s
556
- nativepluck | 1000 | created_at | 196.4 i/s - same-ish: difference falls within error
557
- nativepluck_raw :to_sql | 1000 | created_at | 187.6 i/s - same-ish: difference falls within error
558
- pluck | 1000 | created_at | 45.9 i/s - 4.34x slower
559
- nativepluck_raw SQL_RAW | 1000 | updated_at | 204.4 i/s
560
- nativepluck_raw :to_sql | 1000 | updated_at | 197.2 i/s - same-ish: difference falls within error
561
- nativepluck | 1000 | updated_at | 193.4 i/s - same-ish: difference falls within error
562
- pluck | 1000 | updated_at | 40.9 i/s - 5.00x slower
65
+ * Benchmark code `test/dummy/test/benchmarks/runtime_benchmarks.rb`<br>
66
+ * We're seeing up to ~4X faster run-time when plucking DateTime columns and ~1.5X on integer columns
67
+ * Full results at `test/dummy/test/benchmarks/runtime.csv`
68
+
563
69
 
564
70
  ## License
565
71
 
@@ -13,5 +13,5 @@
13
13
  # limitations under the License.
14
14
 
15
15
  module Nativepluck
16
- VERSION = "0.1.2"
16
+ VERSION = "0.2.0"
17
17
  end
data/lib/nativepluck.rb CHANGED
@@ -15,18 +15,15 @@
15
15
  require "nativepluck/version"
16
16
 
17
17
  module Nativepluck
18
- @nativepluck_init = false
18
+ @override_pluck = @nativepluck_init = false
19
19
 
20
20
  class << self
21
21
  attr_accessor :nativepluck_type_map_for_results, :nativepluck_type_map_for_queries
22
22
  attr_accessor :original_type_map_for_results, :original_type_map_for_queries
23
- attr_accessor :nativepluck_init
23
+ attr_accessor :nativepluck_init, :override_pluck
24
24
  end
25
25
 
26
- def self.included(klass)
27
- klass.extend(ClassMethods)
28
- init_nativepluck
29
- end
26
+
30
27
 
31
28
  def self.init_nativepluck
32
29
  return if @nativepluck_init
@@ -50,6 +47,7 @@ module Nativepluck
50
47
  end
51
48
 
52
49
  def self.nativepluck(input)
50
+ out = []
53
51
  begin
54
52
  sql = input.respond_to?(:to_sql) ? input.to_sql : input
55
53
  Nativepluck.set_pg_native_casters
@@ -62,27 +60,60 @@ module Nativepluck
62
60
  return out
63
61
  end
64
62
 
65
- module ClassMethods
66
- def nativepluck(*columns, **opts)
67
- raise ArgumentError.new('No columns to pluck were provided') if columns.size == 0
68
- begin
69
- Nativepluck.set_pg_native_casters
70
- sql = "
71
- SELECT #{columns.join(',')}
72
- FROM #{self.table_name}
73
- #{"GROUP BY #{opts[:group].zip.map { |i| i.join(' ') }.join(',')}" if opts[:group]}
74
- #{"ORDER BY #{opts[:order].zip.map { |i| i.join(' ') }.join(',')}" if opts[:order]}
75
- #{"LIMIT #{opts[:limit]}" if opts[:limit]}
76
- #{"OFFSET #{opts[:offset]}" if opts[:offset]}
77
- "
78
- results = ActiveRecord::Base.connection.raw_connection.async_exec(sql)
79
- puts "#{__method__} sql = #{sql}" if opts[:verbose]
80
- results.nfields == 1 ? out = results.column_values(0) : out = results.values
81
- ensure
82
- results.try(:clear)
83
- Nativepluck.return_original_casters
63
+ module InstanceMethods
64
+ def nativepluck(*column_names)
65
+ # Extracted (before modifications) from:
66
+ # ruby-2.5.0/gems/activerecord-5.2.1/lib/active_record/relation/calculations.rb
67
+ if loaded? && (column_names.map(&:to_s) - @klass.attribute_names - @klass.attribute_aliases.keys).empty?
68
+ return records.nativepluck(*column_names)
69
+ end
70
+
71
+ if has_include?(column_names.first)
72
+ relation = apply_join_dependency
73
+ relation.nativepluck(*column_names)
74
+ else
75
+ enforce_raw_sql_whitelist(column_names)
76
+ relation = spawn
77
+ relation.select_values = column_names.map { |cn|
78
+ @klass.has_attribute?(cn) || @klass.attribute_alias?(cn) ? arel_attribute(cn) : cn
79
+ }
80
+ Nativepluck.nativepluck(relation)
81
+ end
82
+ end
83
+ end
84
+
85
+ module ::ActiveRecord
86
+ module Calculations
87
+ include Nativepluck::InstanceMethods
88
+ end
89
+ module Querying
90
+ delegate :nativepluck, to: :all
91
+ end
92
+ end
93
+
94
+ def self.set_override_pluck(selection)
95
+ raise ArgumentError.new("#{__method__}:: Input should be true/false and not #{selection.class}") unless (selection.is_a?(TrueClass) || selection.is_a?(FalseClass))
96
+
97
+ if selection
98
+ ::ActiveRecord::Calculations.class_eval do
99
+ alias_method :orig_pluck, :pluck
100
+ alias_method :pluck, :nativepluck
101
+ end
102
+ ::ActiveRecord::Querying.class_eval do
103
+ alias_method :orig_pluck, :pluck
104
+ alias_method :pluck, :nativepluck
105
+ end
106
+ else
107
+ unless Nativepluck.override_pluck
108
+ raise ArgumentError.new("#{__method__}:: Cannot turn off pluck overriding since it wasn't set yet")
109
+ end
110
+ ::ActiveRecord::Calculations.class_eval do
111
+ alias_method :pluck, :orig_pluck
112
+ end
113
+ ::ActiveRecord::Querying.class_eval do
114
+ alias_method :pluck, :orig_pluck
84
115
  end
85
- return out
86
116
  end
117
+ Nativepluck.override_pluck = selection
87
118
  end
88
119
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nativepluck
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ohad Dahan
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-11-12 00:00:00.000000000 Z
12
+ date: 2018-11-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails