Skip to content

Commit 0834e9f

Browse files
committed
Imrove performance
1 parent c2b6a13 commit 0834e9f

File tree

2 files changed

+70
-51
lines changed

2 files changed

+70
-51
lines changed

app/models/repo.rb

Lines changed: 45 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -32,65 +32,59 @@ def generate_sparkline_data
3232
FROM min_max_dates
3333
)
3434
SELECT
35-
subquery.*
35+
benchmark_result_type_id,
36+
benchmark_type_id,
37+
hstore_to_json(br.result) AS result,
38+
category
3639
FROM (
37-
SELECT
38-
benchmark_result_type_id,
39-
benchmark_type_id,
40-
array_to_json(array_agg(br.id)) AS ids
41-
FROM (
42-
SELECT id FROM (
43-
SELECT
44-
ROW_NUMBER() OVER(PARTITION BY w.weekstart ORDER BY c.created_at) AS row_num,
45-
id
46-
FROM weeks w
47-
INNER JOIN commits c
48-
ON w.weekstart = date_trunc('week', c.created_at) AND c.repo_id = #{self.id}
49-
) x
50-
WHERE row_num = 1
51-
) cw
52-
INNER JOIN benchmark_runs br
53-
ON cw.id = br.initiator_id AND br.initiator_type = 'Commit'
54-
INNER JOIN benchmark_types bt
55-
ON bt.id = br.benchmark_type_id AND bt.repo_id = #{self.id}
56-
GROUP BY benchmark_type_id, benchmark_result_type_id
57-
) AS subquery
58-
INNER JOIN benchmark_types
59-
ON benchmark_types.id = subquery.benchmark_type_id
60-
INNER JOIN benchmark_result_types
61-
ON benchmark_result_types.id = subquery.benchmark_result_type_id
62-
ORDER BY category, name
40+
SELECT id, commit_date FROM (
41+
SELECT
42+
ROW_NUMBER() OVER(PARTITION BY w.weekstart ORDER BY c.created_at) AS row_num,
43+
id,
44+
created_at AS commit_date
45+
FROM weeks w
46+
INNER JOIN commits c
47+
ON w.weekstart = date_trunc('week', c.created_at) AND c.repo_id = #{self.id}
48+
) x
49+
WHERE row_num = 1
50+
) cw
51+
INNER JOIN benchmark_runs br
52+
ON cw.id = br.initiator_id AND br.initiator_type = 'Commit'
53+
INNER JOIN benchmark_types bt
54+
ON bt.id = br.benchmark_type_id AND bt.repo_id = #{self.id}
55+
ORDER BY category, commit_date
6356
SQL
6457

65-
results = self.class.connection.execute(query).to_a
66-
results.each do |row|
67-
row['ids'] = JSON.parse(row['ids'])
58+
raw_results = self.class.connection.execute(query).to_a
59+
raw_results.each do |row|
60+
row['result'] = JSON.parse(row['result'])
6861
end
6962

70-
types = self.benchmark_types
71-
.where(id: results.map { |row| row['benchmark_type_id'] }.uniq)
72-
.map { |type| [type.id, type] }.to_h
7363
result_types = BenchmarkResultType
74-
.where(id: results.map { |row| row['benchmark_result_type_id'] }.uniq)
64+
.where(id: raw_results.map { |row| row['benchmark_result_type_id'] }.uniq)
7565
.map { |res_type| [res_type.id, res_type] }.to_h
76-
all_runs = BenchmarkRun
77-
.select(:id, :initiator_id, :result, :initiator_type, 'c.created_at')
78-
.joins("JOIN commits c ON c.id = benchmark_runs.initiator_id AND benchmark_runs.initiator_type = 'Commit'")
79-
.where(id: results.map { |row| row['ids'] }.flatten.uniq)
80-
.map { |run| [run.id, run] }.to_h
81-
82-
results.each do |res|
83-
type = types[res['benchmark_type_id']]
84-
result_type = result_types[res['benchmark_result_type_id']]
85-
runs = all_runs.values_at(*res['ids']).sort_by(&:created_at)
86-
next if !type || !result_type || runs.size == 0
8766

88-
chart_builder = ChartBuilder.new(runs, result_type).build_columns
89-
charts[type.category] ||= []
90-
charts[type.category] << {
91-
benchmark_result_type: result_type.name,
92-
columns: chart_builder.columns
93-
}
67+
results = {}
68+
raw_results.each do |res|
69+
results[res['benchmark_type_id']] ||= {}
70+
results[res['benchmark_type_id']]['category'] = res['category']
71+
hash = results[res['benchmark_type_id']]['res_types'] ||= {}
72+
arr = hash[result_types[res['benchmark_result_type_id']].name] ||= []
73+
arr << res['result']
74+
hash.sort_by { |k| k }
75+
results[res['benchmark_type_id']]['res_types'] = hash.sort_by { |k, v| k }.to_h
76+
end
77+
results.values.each do |res|
78+
category = res['category']
79+
next unless category
80+
res['res_types'].each do |name, runs|
81+
chart_builder = ChartBuilder.new(runs, nil).build_columns_hash
82+
charts[category] ||= []
83+
charts[category] << {
84+
benchmark_result_type: name,
85+
columns: chart_builder.columns
86+
}
87+
end
9488
end
9589

9690
$redis.setex("sparklines:#{self.id}", 1800, charts.to_msgpack)

app/services/chart_builder.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,29 @@ def build_columns
6060
@columns = new_columns
6161
self
6262
end
63+
64+
def build_columns_hash
65+
keys = @benchmark_runs.map { |run| run.keys }.flatten.uniq
66+
@benchmark_runs.each do |benchmark_run|
67+
if block_given?
68+
version = yield(benchmark_run)
69+
@categories ||= []
70+
@categories << version
71+
end
72+
73+
keys.each do |key|
74+
@columns[key] ||= []
75+
@columns[key] << benchmark_run[key]&.to_f
76+
end
77+
end
78+
79+
new_columns = []
80+
81+
@columns.each do |name, data|
82+
new_columns << { name: name, data: data }
83+
end
84+
85+
@columns = new_columns
86+
self
87+
end
6388
end

0 commit comments

Comments
 (0)