|
1 | 1 | use std::collections::HashSet;
|
2 | 2 | use std::io::Read;
|
| 3 | +use std::num::NonZeroUsize; |
3 | 4 | use std::sync::Arc;
|
4 |
| -use std::time::{Duration, Instant}; |
| 5 | +use std::time::Instant; |
5 | 6 |
|
6 | 7 | use bytes::Buf;
|
7 | 8 | use database::CommitType;
|
8 | 9 | use headers::{ContentType, Header};
|
9 | 10 | use hyper::StatusCode;
|
| 11 | +use lru::LruCache; |
10 | 12 |
|
11 |
| -use crate::api::self_profile::{ArtifactSize, ArtifactSizeDelta}; |
| 13 | +use crate::api::self_profile::ArtifactSizeDelta; |
12 | 14 | use crate::api::{self_profile, self_profile_processed, self_profile_raw, ServerResult};
|
13 | 15 | use crate::comparison::Metric;
|
14 | 16 | use crate::db::ArtifactId;
|
15 | 17 | use crate::load::SiteCtxt;
|
16 | 18 | use crate::selector::{self};
|
17 | 19 | use crate::self_profile::{
|
18 |
| - extract_profiling_data, fetch_raw_self_profile_data, get_self_profile_raw_data, |
| 20 | + download_and_analyze_self_profile, get_self_profile_raw_data, SelfProfileWithAnalysis, |
19 | 21 | };
|
20 | 22 | use crate::server::{Response, ResponseHeaders};
|
21 | 23 |
|
@@ -154,85 +156,12 @@ pub async fn handle_self_profile_processed_download(
|
154 | 156 | builder.body(hyper::Body::from(output.data)).unwrap()
|
155 | 157 | }
|
156 | 158 |
|
157 |
| -fn get_self_profile_data( |
158 |
| - cpu_clock: Option<f64>, |
159 |
| - profile: &analyzeme::AnalysisResults, |
160 |
| -) -> ServerResult<self_profile::SelfProfile> { |
161 |
| - let total_time: Duration = profile.query_data.iter().map(|qd| qd.self_time).sum(); |
162 |
| - |
163 |
| - let query_data = profile |
164 |
| - .query_data |
165 |
| - .iter() |
166 |
| - .map(|qd| self_profile::QueryData { |
167 |
| - label: qd.label.as_str().into(), |
168 |
| - self_time: qd.self_time.as_nanos() as u64, |
169 |
| - percent_total_time: ((qd.self_time.as_secs_f64() / total_time.as_secs_f64()) * 100.0) |
170 |
| - as f32, |
171 |
| - number_of_cache_misses: qd.number_of_cache_misses as u32, |
172 |
| - number_of_cache_hits: qd.number_of_cache_hits as u32, |
173 |
| - invocation_count: qd.invocation_count as u32, |
174 |
| - blocked_time: qd.blocked_time.as_nanos() as u64, |
175 |
| - incremental_load_time: qd.incremental_load_time.as_nanos() as u64, |
176 |
| - }) |
177 |
| - .collect(); |
178 |
| - |
179 |
| - let totals = self_profile::QueryData { |
180 |
| - label: "Totals".into(), |
181 |
| - self_time: total_time.as_nanos() as u64, |
182 |
| - // TODO: check against wall-time from perf stats |
183 |
| - percent_total_time: cpu_clock |
184 |
| - .map(|w| ((total_time.as_secs_f64() / w) * 100.0) as f32) |
185 |
| - // sentinel "we couldn't compute this time" |
186 |
| - .unwrap_or(-100.0), |
187 |
| - number_of_cache_misses: profile |
188 |
| - .query_data |
189 |
| - .iter() |
190 |
| - .map(|qd| qd.number_of_cache_misses as u32) |
191 |
| - .sum(), |
192 |
| - number_of_cache_hits: profile |
193 |
| - .query_data |
194 |
| - .iter() |
195 |
| - .map(|qd| qd.number_of_cache_hits as u32) |
196 |
| - .sum(), |
197 |
| - invocation_count: profile |
198 |
| - .query_data |
199 |
| - .iter() |
200 |
| - .map(|qd| qd.invocation_count as u32) |
201 |
| - .sum(), |
202 |
| - blocked_time: profile |
203 |
| - .query_data |
204 |
| - .iter() |
205 |
| - .map(|qd| qd.blocked_time.as_nanos() as u64) |
206 |
| - .sum(), |
207 |
| - incremental_load_time: profile |
208 |
| - .query_data |
209 |
| - .iter() |
210 |
| - .map(|qd| qd.incremental_load_time.as_nanos() as u64) |
211 |
| - .sum(), |
212 |
| - }; |
213 |
| - |
214 |
| - let artifact_sizes = profile |
215 |
| - .artifact_sizes |
216 |
| - .iter() |
217 |
| - .map(|a| ArtifactSize { |
218 |
| - label: a.label.as_str().into(), |
219 |
| - bytes: a.value, |
220 |
| - }) |
221 |
| - .collect(); |
222 |
| - |
223 |
| - Ok(self_profile::SelfProfile { |
224 |
| - query_data, |
225 |
| - totals, |
226 |
| - artifact_sizes: Some(artifact_sizes), |
227 |
| - }) |
228 |
| -} |
229 |
| - |
230 | 159 | // Add query data entries to `profile` for any queries in `base_profile` which are not present in
|
231 | 160 | // `profile` (i.e. queries not invoked during the compilation that generated `profile`). This is
|
232 | 161 | // bit of a hack to enable showing rows for these queries in the table on the self-profile page.
|
233 | 162 | fn add_uninvoked_base_profile_queries(
|
234 | 163 | profile: &mut self_profile::SelfProfile,
|
235 |
| - base_profile: &Option<self_profile::SelfProfile>, |
| 164 | + base_profile: Option<&self_profile::SelfProfile>, |
236 | 165 | ) {
|
237 | 166 | let base_profile = match base_profile.as_ref() {
|
238 | 167 | Some(bp) => bp,
|
@@ -265,7 +194,7 @@ fn add_uninvoked_base_profile_queries(
|
265 | 194 |
|
266 | 195 | fn get_self_profile_delta(
|
267 | 196 | profile: &self_profile::SelfProfile,
|
268 |
| - base_profile: &Option<self_profile::SelfProfile>, |
| 197 | + base_profile: Option<&self_profile::SelfProfile>, |
269 | 198 | profiling_data: &analyzeme::AnalysisResults,
|
270 | 199 | base_profiling_data: Option<&analyzeme::AnalysisResults>,
|
271 | 200 | ) -> Option<self_profile::SelfProfileDelta> {
|
@@ -606,45 +535,44 @@ pub async fn handle_self_profile(
|
606 | 535 | assert_eq!(cpu_responses.len(), 1, "all selectors are exact");
|
607 | 536 | let mut cpu_response = cpu_responses.remove(0).series;
|
608 | 537 |
|
609 |
| - let mut self_profile_data = Vec::new(); |
610 |
| - let conn = ctxt.conn().await; |
611 |
| - for commit in commits.iter() { |
612 |
| - let aids_and_cids = conn |
613 |
| - .list_self_profile(commit.clone(), bench_name, profile, &body.scenario) |
614 |
| - .await; |
615 |
| - if let Some((aid, cid)) = aids_and_cids.first() { |
616 |
| - match fetch_raw_self_profile_data(*aid, bench_name, profile, scenario, *cid).await { |
617 |
| - Ok(d) => self_profile_data.push( |
618 |
| - extract_profiling_data(d) |
619 |
| - .map_err(|e| format!("error extracting self profiling data: {}", e))?, |
620 |
| - ), |
621 |
| - Err(e) => return Err(format!("could not fetch raw profile data: {e:?}")), |
622 |
| - }; |
623 |
| - } |
624 |
| - } |
625 |
| - let profiling_data = self_profile_data.remove(0).perform_analysis(); |
626 |
| - let mut profile = get_self_profile_data(cpu_response.next().unwrap().1, &profiling_data) |
627 |
| - .map_err(|e| format!("{}: {}", body.commit, e))?; |
628 |
| - let (base_profile, base_raw_data) = if body.base_commit.is_some() { |
629 |
| - let base_profiling_data = self_profile_data.remove(0).perform_analysis(); |
630 |
| - let profile = get_self_profile_data(cpu_response.next().unwrap().1, &base_profiling_data) |
631 |
| - .map_err(|e| format!("{}: {}", body.base_commit.as_ref().unwrap(), e))?; |
632 |
| - (Some(profile), Some(base_profiling_data)) |
633 |
| - } else { |
634 |
| - (None, None) |
| 538 | + let mut self_profile = download_and_analyze_self_profile( |
| 539 | + ctxt, |
| 540 | + commits.get(0).unwrap().clone(), |
| 541 | + &bench_name, |
| 542 | + profile, |
| 543 | + scenario, |
| 544 | + cpu_response.next().unwrap().1, |
| 545 | + ) |
| 546 | + .await?; |
| 547 | + let base_self_profile = match commits.get(1) { |
| 548 | + Some(aid) => Some( |
| 549 | + download_and_analyze_self_profile( |
| 550 | + ctxt, |
| 551 | + aid.clone(), |
| 552 | + &bench_name, |
| 553 | + profile, |
| 554 | + scenario, |
| 555 | + cpu_response.next().unwrap().1, |
| 556 | + ) |
| 557 | + .await?, |
| 558 | + ), |
| 559 | + None => None, |
635 | 560 | };
|
| 561 | + add_uninvoked_base_profile_queries( |
| 562 | + &mut self_profile.profile, |
| 563 | + base_self_profile.as_ref().map(|p| &p.profile), |
| 564 | + ); |
636 | 565 |
|
637 |
| - add_uninvoked_base_profile_queries(&mut profile, &base_profile); |
638 | 566 | let mut base_profile_delta = get_self_profile_delta(
|
639 |
| - &profile, |
640 |
| - &base_profile, |
641 |
| - &profiling_data, |
642 |
| - base_raw_data.as_ref(), |
| 567 | + &self_profile.profile, |
| 568 | + base_self_profile.as_ref().map(|p| &p.profile), |
| 569 | + &self_profile.profiling_data, |
| 570 | + base_self_profile.as_ref().map(|p| &p.profiling_data), |
643 | 571 | );
|
644 |
| - sort_self_profile(&mut profile, &mut base_profile_delta, sort_idx); |
| 572 | + sort_self_profile(&mut self_profile.profile, &mut base_profile_delta, sort_idx); |
645 | 573 |
|
646 | 574 | Ok(self_profile::Response {
|
647 | 575 | base_profile_delta,
|
648 |
| - profile, |
| 576 | + profile: self_profile.profile, |
649 | 577 | })
|
650 | 578 | }
|
0 commit comments