mini_sql 0.1.0 → 0.1.1

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: 2d984e77f8a88e9996f5d014bc4543de0872717cc916f511f3a6fb02c043b2e5
4
- data.tar.gz: 827f2319fef84d2ab143336cc24b004c4644e4d8f38bd070b7a3f5795a791cc1
3
+ metadata.gz: 5b4a853f294d878decdf635afbfe2ef4029fe994ec710172038ec2a9ac664980
4
+ data.tar.gz: 278a68ac45dda9070d30fd08d98ca9bb93ea6c8e5b378d7ebe7f085620797c77
5
5
  SHA512:
6
- metadata.gz: 1ae8290a5f6aa4831fc8392813f54a6b2d122bafe6ab285e20604794a8fc15ad39fe2fd98d86767a46486d45ef6bb522038b190b081a99dd7344953e692445a6
7
- data.tar.gz: ef68d1d15da7b7f1ed17e831fcc5fd49c9c109112b481c3489e75097d1ad9d670929c5689e5849211b9cbcdefd19573cd65d47aca8c17b3b58d3a86a53a6ecf4
6
+ metadata.gz: ae6b7f73423e5001d80f0fc027fe0f2c557ac4961c1868e642087c50b8147bf2fca8b3431f8bec2603c33d762c533be57bb742d1ea5983481b4c3045ca348e73
7
+ data.tar.gz: c6628d1b1ce3b9c2d0f6f553370f705f649d643c25ec1a524415fb5f3c871a9c93f80834698d6df8b82b04012917baaf3ada442bea585ddce3692bcc7af40870
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mini_sql (0.1.0)
4
+ mini_sql (0.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -0,0 +1,240 @@
1
+ require 'bundler/inline'
2
+
3
+ gemfile do
4
+ source 'https://rubygems.org'
5
+ gem 'pg'
6
+ gem 'mini_sql', path: '../'
7
+ gem 'activesupport'
8
+ gem 'activerecord'
9
+ gem 'activemodel'
10
+ gem 'memory_profiler'
11
+ gem 'benchmark-ips'
12
+ gem 'sequel'
13
+ gem 'sequel_pg', require: 'sequel'
14
+ end
15
+
16
+ require 'sequel'
17
+ require 'active_record'
18
+ require 'memory_profiler'
19
+ require 'benchmark/ips'
20
+ require 'mini_sql'
21
+
22
+ ActiveRecord::Base.establish_connection(
23
+ :adapter => "postgresql",
24
+ :database => "test_db"
25
+ )
26
+
27
+ DB = Sequel.postgres('test_db')
28
+
29
+ pg = ActiveRecord::Base.connection.raw_connection
30
+
31
+ pg.async_exec <<SQL
32
+ drop table if exists topics
33
+ SQL
34
+
35
+ pg.async_exec <<SQL
36
+ CREATE TABLE topics (
37
+ id integer NOT NULL,
38
+ title character varying NOT NULL,
39
+ last_posted_at timestamp without time zone,
40
+ created_at timestamp without time zone NOT NULL,
41
+ updated_at timestamp without time zone NOT NULL,
42
+ views integer DEFAULT 0 NOT NULL,
43
+ posts_count integer DEFAULT 0 NOT NULL,
44
+ user_id integer,
45
+ last_post_user_id integer NOT NULL,
46
+ reply_count integer DEFAULT 0 NOT NULL,
47
+ featured_user1_id integer,
48
+ featured_user2_id integer,
49
+ featured_user3_id integer,
50
+ avg_time integer,
51
+ deleted_at timestamp without time zone,
52
+ highest_post_number integer DEFAULT 0 NOT NULL,
53
+ image_url character varying,
54
+ like_count integer DEFAULT 0 NOT NULL,
55
+ incoming_link_count integer DEFAULT 0 NOT NULL,
56
+ category_id integer,
57
+ visible boolean DEFAULT true NOT NULL,
58
+ moderator_posts_count integer DEFAULT 0 NOT NULL,
59
+ closed boolean DEFAULT false NOT NULL,
60
+ archived boolean DEFAULT false NOT NULL,
61
+ bumped_at timestamp without time zone NOT NULL,
62
+ has_summary boolean DEFAULT false NOT NULL,
63
+ vote_count integer DEFAULT 0 NOT NULL,
64
+ archetype character varying DEFAULT 'regular'::character varying NOT NULL,
65
+ featured_user4_id integer,
66
+ notify_moderators_count integer DEFAULT 0 NOT NULL,
67
+ spam_count integer DEFAULT 0 NOT NULL,
68
+ pinned_at timestamp without time zone,
69
+ score double precision,
70
+ percent_rank double precision DEFAULT 1.0 NOT NULL,
71
+ subtype character varying,
72
+ slug character varying,
73
+ deleted_by_id integer,
74
+ participant_count integer DEFAULT 1,
75
+ word_count integer,
76
+ excerpt character varying(1000),
77
+ pinned_globally boolean DEFAULT false NOT NULL,
78
+ pinned_until timestamp without time zone,
79
+ fancy_title character varying(400),
80
+ highest_staff_post_number integer DEFAULT 0 NOT NULL,
81
+ featured_link character varying
82
+ )
83
+ SQL
84
+
85
+ class Topic < ActiveRecord::Base
86
+ end
87
+
88
+ class TopicSequel < Sequel::Model(:topics)
89
+ end
90
+
91
+
92
+ Topic.transaction do
93
+ topic = {
94
+ }
95
+ Topic.columns.each do |c|
96
+ topic[c.name.to_sym] = case c.type
97
+ when :integer then 1
98
+ when :datetime then Time.now
99
+ when :boolean then false
100
+ else "HELLO WORLD" * 2
101
+ end
102
+ end
103
+
104
+ 1000.times do |id|
105
+ topic[:id] = id
106
+ Topic.create!(topic)
107
+ end
108
+ end
109
+
110
+ $conn = ActiveRecord::Base.connection.raw_connection
111
+
112
+ def ar_title_id_pluck
113
+ s = +""
114
+ Topic.limit(1000).order(:id).pluck(:id, :title).each do |id, title|
115
+ s << id.to_s
116
+ s << title
117
+ end
118
+ s
119
+ end
120
+
121
+ def ar_title_id
122
+ s = +""
123
+ Topic.limit(1000).order(:id).select(:id, :title).each do |t|
124
+ s << t.id.to_s
125
+ s << t.title
126
+ end
127
+ s
128
+ end
129
+
130
+ def pg_title_id
131
+ s = +""
132
+ # use the safe pattern here
133
+ r = $conn.async_exec(-"select id, title from topics order by id limit 1000")
134
+ r.each do |row|
135
+ s << row["id"].to_s
136
+ s << row["title"]
137
+ end
138
+ r.clear
139
+ s
140
+ end
141
+
142
+ $mini_sql = MiniSql::Connection.new($conn)
143
+
144
+ def mini_sql_title_id
145
+ s = +""
146
+ $mini_sql.query(-"select id, title from topics order by id limit 1000").each do |t|
147
+ s << t.id.to_s
148
+ s << t.title
149
+ end
150
+ s
151
+ end
152
+
153
+ def sequel_select_title_id
154
+ s = +""
155
+ TopicSequel.limit(1000).order(:id).select(:id, :title).each do |t|
156
+ s << t.id.to_s
157
+ s << t.title
158
+ end
159
+ s
160
+ end
161
+
162
+ def sequel_pluck_title_id
163
+ s = +""
164
+ TopicSequel.limit(1000).order(:id).select_map([:id, :title]).each do |t|
165
+ s << t[0].to_s
166
+ s << t[1]
167
+ end
168
+ s
169
+ end
170
+
171
+ results = [ar_title_id, ar_title_id_pluck, pg_title_id, mini_sql_title_id, sequel_pluck_title_id, sequel_select_title_id]
172
+
173
+ exit(-1) unless results.uniq.length == 1
174
+
175
+ Benchmark.ips do |r|
176
+ r.report("ar select title id") do |n|
177
+ while n > 0
178
+ ar_title_id
179
+ n -= 1
180
+ end
181
+ end
182
+ r.report("ar select title id pluck") do |n|
183
+ while n > 0
184
+ ar_title_id_pluck
185
+ n -= 1
186
+ end
187
+ end
188
+ r.report("sequel title id select") do |n|
189
+ while n > 0
190
+ sequel_select_title_id
191
+ n -= 1
192
+ end
193
+ end
194
+ r.report("sequel title id pluck") do |n|
195
+ while n > 0
196
+ sequel_pluck_title_id
197
+ n -= 1
198
+ end
199
+ end
200
+ r.report("pg select title id") do |n|
201
+ while n > 0
202
+ pg_title_id
203
+ n -= 1
204
+ end
205
+ end
206
+ r.report("mini_sql select title id") do |n|
207
+ while n > 0
208
+ mini_sql_title_id
209
+ n -= 1
210
+ end
211
+ end
212
+ r.compare!
213
+ end
214
+
215
+
216
+ # Calculating -------------------------------------
217
+ # ar select title id 144.043 (± 1.4%) i/s - 728.000 in 5.055454s
218
+ # ar select title id pluck
219
+ # 712.818 (± 1.5%) i/s - 3.570k in 5.009412s
220
+ # sequel title id select
221
+ # 927.011 (± 1.8%) i/s - 4.655k in 5.023228s
222
+ # sequel title id pluck
223
+ # 1.183k (± 3.2%) i/s - 5.967k in 5.048635s
224
+ # pg select title id 1.040k (± 1.4%) i/s - 5.253k in 5.051679s
225
+ # mini_sql select title id
226
+ # 1.139k (± 2.5%) i/s - 5.712k in 5.016383s
227
+ #
228
+ # Comparison:
229
+ # sequel title id pluck: 1183.1 i/s
230
+ # mini_sql select title id: 1139.3 i/s - same-ish: difference falls within error
231
+ # pg select title id: 1040.1 i/s - 1.14x slower
232
+ # sequel title id select: 927.0 i/s - 1.28x slower
233
+ # ar select title id pluck: 712.8 i/s - 1.66x slower
234
+ # ar select title id: 144.0 i/s - 8.21x slower
235
+ #
236
+ # to run deep analysis run
237
+ # MemoryProfiler.report do
238
+ # ar
239
+ # end.pretty_print
240
+
@@ -44,7 +44,7 @@ module MiniSql
44
44
  instance_eval <<~RUBY
45
45
  def materialize(pg_result, index)
46
46
  r = self.new
47
- #{col=-1; fields.map{|f| "r.#{f} = pg_result.getvalue(index, #{col+=1})"}.join('\n')}
47
+ #{col=-1; fields.map{|f| "r.#{f} = pg_result.getvalue(index, #{col+=1})"}.join("; ")}
48
48
  r
49
49
  end
50
50
  RUBY
@@ -1,3 +1,3 @@
1
1
  module MiniSql
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini_sql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
@@ -110,6 +110,7 @@ files:
110
110
  - LICENSE.txt
111
111
  - README.md
112
112
  - Rakefile
113
+ - bench/topic_perf.rb
113
114
  - bin/console
114
115
  - bin/setup
115
116
  - lib/mini_sql.rb