activerecord-has_count 0.0.3 → 0.0.4
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/benchmarks/Gemfile +0 -1
- data/benchmarks/benchmark.rb +53 -23
- data/lib/active_record/associations/preloader/has_count.rb +15 -0
- data/lib/activerecord-has_count/version.rb +1 -1
- data/spec/models/reply.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d2c85db920895de37cc5f38524f2fb8ae76b3eb
|
4
|
+
data.tar.gz: 9ad1ad18db8c6fc038328a30490bba0d1593b632
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a100ee2738250cc1049089571609d7d7c166c198576440d4c3d9a52f6da78c5bc0d02dcef8b133e6dc8b7eb9bdc9281aeec53f5d495a33fd31c5f19db054657
|
7
|
+
data.tar.gz: 62e8e5db5e59aa2b792344733501881db3df81e53bea8779634220668335f3f648a0b83dbcaf7018f163f45621199f3fd46bc8e7848a345344ceb84ce2092b3a
|
data/benchmarks/Gemfile
CHANGED
data/benchmarks/benchmark.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require "benchmark"
|
2
2
|
require "pry"
|
3
3
|
require "active_record"
|
4
|
-
require "activerecord-import"
|
5
4
|
require "activerecord-has_count"
|
6
5
|
|
7
6
|
spec_dir = File.expand_path("../../spec", __FILE__)
|
@@ -11,57 +10,88 @@ database_yml = File.join(spec_dir, "database.yml")
|
|
11
10
|
ActiveRecord::Base.configurations["bench"] = YAML.load_file(database_yml)["bench"]
|
12
11
|
ActiveRecord::Base.establish_connection :bench
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
def silently_execute(&block)
|
14
|
+
stdout_old = $stdout.dup
|
15
|
+
$stdout.reopen("/tmp/bench")
|
16
|
+
block.call
|
17
|
+
$stdout.flush
|
18
|
+
$stdout.reopen stdout_old
|
19
|
+
end
|
20
|
+
|
21
|
+
def assert_equal(expect, actual)
|
22
|
+
raise "Expected #{expect}, but got #{actual}" if expect != actual
|
23
|
+
end
|
19
24
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
silently_execute do
|
26
|
+
ActiveRecord::Schema.define do
|
27
|
+
create_table :tweets, force: true do |t|
|
28
|
+
t.column :replies_count_cache, :integer
|
29
|
+
t.column :created_at, :datetime
|
30
|
+
t.column :updated_at, :datetime
|
31
|
+
end
|
32
|
+
|
33
|
+
create_table :replies, force: true do |t|
|
34
|
+
t.column :tweet_id, :integer
|
35
|
+
t.column :created_at, :datetime
|
36
|
+
t.column :updated_at, :datetime
|
37
|
+
end
|
38
|
+
add_index :replies, [:tweet_id], name: "index_replies_on_tweet_id", using: :btree
|
24
39
|
end
|
25
40
|
end
|
26
41
|
|
27
42
|
[Tweet, Reply].each(&:delete_all)
|
28
43
|
|
29
|
-
TWEET_COUNT =
|
30
|
-
REPLY_COUNT =
|
44
|
+
TWEET_COUNT = 10
|
45
|
+
REPLY_COUNT = 1000
|
31
46
|
|
32
47
|
TWEET_COUNT.times do
|
33
|
-
tweet = Tweet.create
|
48
|
+
tweet = Tweet.create(replies_count_cache: 0)
|
34
49
|
|
35
50
|
replies = REPLY_COUNT.times.map do
|
36
|
-
Reply.
|
51
|
+
Reply.create(tweet: tweet)
|
37
52
|
end
|
38
|
-
Reply.import(replies, validate: false)
|
39
53
|
end
|
40
54
|
|
41
|
-
Benchmark.
|
42
|
-
bench.report("
|
55
|
+
Benchmark.bm do |bench|
|
56
|
+
bench.report("counter_cache ") do
|
57
|
+
tweets = Tweet.first(TWEET_COUNT)
|
58
|
+
|
59
|
+
tweets.each do |t|
|
60
|
+
assert_equal(REPLY_COUNT, t.replies_count_cache)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
bench.report("N+1 COUNT query ") do
|
43
65
|
tweets = Tweet.first(TWEET_COUNT)
|
44
66
|
|
45
|
-
tweets.each
|
67
|
+
tweets.each do |t|
|
68
|
+
assert_equal(REPLY_COUNT, t.replies.count)
|
69
|
+
end
|
46
70
|
end
|
47
71
|
|
48
|
-
bench.report("LEFT JOIN") do
|
72
|
+
bench.report("LEFT JOIN ") do
|
49
73
|
tweets = Tweet.joins('LEFT JOIN replies ON tweets.id = replies.tweet_id').
|
50
74
|
select('tweets.*, COUNT(replies.id) AS replies_count').
|
51
75
|
group('tweets.id').first(TWEET_COUNT)
|
52
76
|
|
53
|
-
tweets.each
|
77
|
+
tweets.each do |t|
|
78
|
+
assert_equal(REPLY_COUNT, t.replies_count)
|
79
|
+
end
|
54
80
|
end
|
55
81
|
|
56
82
|
bench.report("preloaded has_count") do
|
57
83
|
tweets = Tweet.preload(:replies_count).first(TWEET_COUNT)
|
58
84
|
|
59
|
-
tweets.each
|
85
|
+
tweets.each do |t|
|
86
|
+
assert_equal(REPLY_COUNT, t.replies_count)
|
87
|
+
end
|
60
88
|
end
|
61
89
|
|
62
|
-
bench.report("
|
90
|
+
bench.report("preloaded has_many ") do
|
63
91
|
tweets = Tweet.preload(:replies).first(TWEET_COUNT)
|
64
92
|
|
65
|
-
tweets.each
|
93
|
+
tweets.each do |t|
|
94
|
+
assert_equal(REPLY_COUNT, t.replies.size)
|
95
|
+
end
|
66
96
|
end
|
67
97
|
end
|
@@ -20,6 +20,21 @@ module ActiveRecord
|
|
20
20
|
association.target = count
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
def load_slices(slices)
|
25
|
+
@preloaded_records = slices.flat_map { |slice|
|
26
|
+
records_for(slice)
|
27
|
+
}
|
28
|
+
|
29
|
+
@preloaded_records.map { |record|
|
30
|
+
key = record
|
31
|
+
[record, key]
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def query_scope(ids)
|
36
|
+
scope.where(association_key.in(ids)).pluck(association_key_name)
|
37
|
+
end
|
23
38
|
end
|
24
39
|
|
25
40
|
private
|
data/spec/models/reply.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -15,7 +15,7 @@ ActiveRecord::Base.establish_connection :test
|
|
15
15
|
|
16
16
|
ActiveRecord::Schema.define do
|
17
17
|
create_table :tweets, force: true do |t|
|
18
|
-
t.column :
|
18
|
+
t.column :replies_count_cache, :integer
|
19
19
|
t.column :created_at, :datetime
|
20
20
|
t.column :updated_at, :datetime
|
21
21
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-has_count
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takashi Kokubun
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|