|
1
|
require 'benchmark'
|
|
2
|
|
|
3
|
users_count = (ENV['USERS_COUNT'] || '10000').to_i
|
|
4
|
iterations = (ENV['ITER'] || '10').to_i
|
|
5
|
mentions_count = (ENV['MENTIONS_COUNT'] || '100').to_i
|
|
6
|
|
|
7
|
Setting.text_formatting = 'common_mark'
|
|
8
|
Setting.cache_formatted_text = 0
|
|
9
|
|
|
10
|
puts "ruby=#{RUBY_VERSION} db=#{ActiveRecord::Base.connection.adapter_name} users=#{users_count} mentions_per_text=#{mentions_count} iter=#{iterations}"
|
|
11
|
|
|
12
|
class SimpleHelper
|
|
13
|
include ApplicationHelper
|
|
14
|
include ActionView::Helpers::TagHelper
|
|
15
|
include ActionView::Helpers::AssetTagHelper
|
|
16
|
include ActionView::Helpers::UrlHelper
|
|
17
|
include Rails.application.routes.url_helpers
|
|
18
|
|
|
19
|
def controller
|
|
20
|
nil
|
|
21
|
end
|
|
22
|
|
|
23
|
def current_menu_item
|
|
24
|
nil
|
|
25
|
end
|
|
26
|
end
|
|
27
|
|
|
28
|
helper = SimpleHelper.new
|
|
29
|
|
|
30
|
ActiveRecord::Base.transaction do
|
|
31
|
puts "Inserting users..."
|
|
32
|
total_inserted = 0
|
|
33
|
|
|
34
|
users_count.times.each_slice(10000) do |slice|
|
|
35
|
users_attrs = slice.map do |i|
|
|
36
|
{
|
|
37
|
login: "bench_user_#{i}",
|
|
38
|
firstname: "Bench",
|
|
39
|
lastname: "User #{i}",
|
|
40
|
status: Principal::STATUS_ACTIVE,
|
|
41
|
type: 'User',
|
|
42
|
language: 'en',
|
|
43
|
created_on: Time.now,
|
|
44
|
updated_on: Time.now
|
|
45
|
}
|
|
46
|
end
|
|
47
|
User.insert_all(users_attrs)
|
|
48
|
total_inserted += users_attrs.size
|
|
49
|
print "."
|
|
50
|
end
|
|
51
|
puts "\nUsers inserted: #{total_inserted}"
|
|
52
|
|
|
53
|
sample_users = User.where("login LIKE 'bench_user_%'").limit(mentions_count).to_a
|
|
54
|
|
|
55
|
if sample_users.length < mentions_count
|
|
56
|
puts "Warning: Only #{sample_users.length} users generated"
|
|
57
|
end
|
|
58
|
|
|
59
|
project = Project.find(1)
|
|
60
|
role = Role.givable.first
|
|
61
|
|
|
62
|
puts "Assigning sample users to project..."
|
|
63
|
# Only add the sampled users to the project for speed
|
|
64
|
member_attrs = sample_users.map do |u|
|
|
65
|
{
|
|
66
|
user_id: u.id,
|
|
67
|
project_id: project.id,
|
|
68
|
created_on: Time.now
|
|
69
|
}
|
|
70
|
end
|
|
71
|
|
|
72
|
Member.insert_all(member_attrs) if member_attrs.any?
|
|
73
|
|
|
74
|
# Also need member_roles
|
|
75
|
members = Member.where(user_id: sample_users.map(&:id)).pluck(:id)
|
|
76
|
member_role_attrs = members.map do |member_id|
|
|
77
|
{
|
|
78
|
member_id: member_id,
|
|
79
|
role_id: role.id
|
|
80
|
}
|
|
81
|
end
|
|
82
|
|
|
83
|
MemberRole.insert_all(member_role_attrs) if member_role_attrs.any?
|
|
84
|
|
|
85
|
text_login = sample_users.map { |u| "@#{u.login}" }.join(" ")
|
|
86
|
text_user_link = sample_users.map { |u| "user##{u.id}" }.join(" ")
|
|
87
|
|
|
88
|
# Worst case: mentions that look valid but don't exist in the DB,
|
|
89
|
# forcing a sequential scan across all rows
|
|
90
|
text_invalid_login = (1..mentions_count).map { |i| "@missing_user_#{i}" }.join(" ")
|
|
91
|
|
|
92
|
prefix = "Here are some mentions: "
|
|
93
|
text_login = prefix + text_login
|
|
94
|
text_user_link = prefix + text_user_link
|
|
95
|
text_invalid_login = prefix + text_invalid_login
|
|
96
|
|
|
97
|
# Warm up
|
|
98
|
helper.textilizable(text_login, project: project)
|
|
99
|
helper.textilizable(text_user_link, project: project)
|
|
100
|
helper.textilizable(text_invalid_login, project: project)
|
|
101
|
|
|
102
|
puts "\nBenchmarking @login..."
|
|
103
|
bm_login = Benchmark.realtime do
|
|
104
|
ApplicationRecord.uncached do
|
|
105
|
iterations.times { helper.textilizable(text_login, project: project) }
|
|
106
|
end
|
|
107
|
end
|
|
108
|
puts "login_ms=#{(bm_login*1000).round(2)} avg_login=#{(bm_login*1000/iterations).round(2)}"
|
|
109
|
|
|
110
|
puts "\nBenchmarking user#id..."
|
|
111
|
bm_user_link = Benchmark.realtime do
|
|
112
|
ApplicationRecord.uncached do
|
|
113
|
iterations.times { helper.textilizable(text_user_link, project: project) }
|
|
114
|
end
|
|
115
|
end
|
|
116
|
puts "user_link_ms=#{(bm_user_link*1000).round(2)} avg_user_link=#{(bm_user_link*1000/iterations).round(2)}"
|
|
117
|
|
|
118
|
puts "\nBenchmarking @login (worst-case non-existent, forces full scan)..."
|
|
119
|
bm_invalid_login = Benchmark.realtime do
|
|
120
|
ApplicationRecord.uncached do
|
|
121
|
iterations.times { helper.textilizable(text_invalid_login, project: project) }
|
|
122
|
end
|
|
123
|
end
|
|
124
|
puts "invalid_login_ms=#{(bm_invalid_login*1000).round(2)} avg_invalid_login=#{(bm_invalid_login*1000/iterations).round(2)}"
|
|
125
|
|
|
126
|
raise ActiveRecord::Rollback
|
|
127
|
end
|