aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorMichal Terepeta <[email protected]>2020-01-11 18:09:31 +0000
committerMichal Terepeta <[email protected]>2020-01-19 17:34:40 +0000
commite8acf49088f90d8d4439c4034696bc4e5f8b4ed9 (patch)
treec88da3a3b0aa95f16c5a82c7c43f75c72792ab78 /crates
parent3a7724e44181ccd5c248589538bd82458b5a9407 (diff)
Fix a corner case when printing unaccounted time
Previously `ra_prof` wouldn't actually print the unaccounted time in some cases. We would print, for instance, this: ``` 5ms - foo 2ms - bar ``` instead of: ``` 5ms - foo 2ms - bar 3ms - ??? ``` The fix is to properly handle the case when an entry has 0 children instead of using the `last` variable. Signed-off-by: Michal Terepeta <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_prof/src/lib.rs56
1 files changed, 52 insertions, 4 deletions
diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs
index 6dde304b1..da541005a 100644
--- a/crates/ra_prof/src/lib.rs
+++ b/crates/ra_prof/src/lib.rs
@@ -219,7 +219,11 @@ fn print(
219 longer_than: Duration, 219 longer_than: Duration,
220 total: Option<Duration>, 220 total: Option<Duration>,
221) { 221) {
222 let mut last = 0; 222 if msgs.is_empty() {
223 return;
224 }
225 // The index of the first element that will be included in the slice when we recurse.
226 let mut next_start = 0;
223 let indent = repeat(" ").take(lvl).collect::<String>(); 227 let indent = repeat(" ").take(lvl).collect::<String>();
224 // We output hierarchy for long calls, but sum up all short calls 228 // We output hierarchy for long calls, but sum up all short calls
225 let mut short = Vec::new(); 229 let mut short = Vec::new();
@@ -233,12 +237,12 @@ fn print(
233 writeln!(out, "{}{:5}ms - {}", indent, duration.as_millis(), msg) 237 writeln!(out, "{}{:5}ms - {}", indent, duration.as_millis(), msg)
234 .expect("printing profiling info to stdout"); 238 .expect("printing profiling info to stdout");
235 239
236 print(lvl + 1, &msgs[last..i], out, longer_than, Some(duration)); 240 print(lvl + 1, &msgs[next_start..i], out, longer_than, Some(duration));
237 } else { 241 } else {
238 short.push((msg, duration)) 242 short.push((msg, duration))
239 } 243 }
240 244
241 last = i; 245 next_start = i + 1;
242 } 246 }
243 short.sort_by_key(|(msg, _time)| *msg); 247 short.sort_by_key(|(msg, _time)| *msg);
244 for (msg, entires) in short.iter().group_by(|(msg, _time)| msg).into_iter() { 248 for (msg, entires) in short.iter().group_by(|(msg, _time)| msg).into_iter() {
@@ -255,7 +259,7 @@ fn print(
255 if let Some(total) = total { 259 if let Some(total) = total {
256 if let Some(unaccounted) = total.checked_sub(accounted_for) { 260 if let Some(unaccounted) = total.checked_sub(accounted_for) {
257 let unaccounted_millis = unaccounted.as_millis(); 261 let unaccounted_millis = unaccounted.as_millis();
258 if unaccounted_millis > longer_than.as_millis() && unaccounted_millis > 0 && last > 0 { 262 if unaccounted_millis > longer_than.as_millis() && unaccounted_millis > 0 {
259 writeln!(out, "{}{:5}ms - ???", indent, unaccounted_millis) 263 writeln!(out, "{}{:5}ms - ???", indent, unaccounted_millis)
260 .expect("printing profiling info to stdout"); 264 .expect("printing profiling info to stdout");
261 } 265 }
@@ -377,4 +381,48 @@ mod tests {
377 " 1ms - foo\n 0ms - bar (2 calls)\n" 381 " 1ms - foo\n 0ms - bar (2 calls)\n"
378 ); 382 );
379 } 383 }
384
385 #[test]
386 fn test_unaccounted_for_topmost() {
387 let mut result = vec![];
388 let msgs = vec![
389 Message { level: 1, duration: Duration::from_millis(2), message: "bar".to_owned() },
390 Message { level: 0, duration: Duration::from_millis(5), message: "foo".to_owned() },
391 ];
392 print(0, &msgs, &mut result, Duration::from_millis(0), Some(Duration::from_millis(1)));
393 assert_eq!(
394 std::str::from_utf8(&result).unwrap().lines().collect::<Vec<_>>(),
395 vec![
396 " 5ms - foo",
397 " 2ms - bar",
398 " 3ms - ???",
399 // Dummy comment to improve formatting
400 ]
401 );
402 }
403
404 #[test]
405 fn test_unaccounted_for_multiple_levels() {
406 let mut result = vec![];
407 let msgs = vec![
408 Message { level: 2, duration: Duration::from_millis(3), message: "baz".to_owned() },
409 Message { level: 1, duration: Duration::from_millis(5), message: "bar".to_owned() },
410 Message { level: 2, duration: Duration::from_millis(2), message: "baz".to_owned() },
411 Message { level: 1, duration: Duration::from_millis(4), message: "bar".to_owned() },
412 Message { level: 0, duration: Duration::from_millis(9), message: "foo".to_owned() },
413 ];
414 print(0, &msgs, &mut result, Duration::from_millis(0), None);
415 assert_eq!(
416 std::str::from_utf8(&result).unwrap().lines().collect::<Vec<_>>(),
417 vec![
418 " 9ms - foo",
419 " 5ms - bar",
420 " 3ms - baz",
421 " 2ms - ???",
422 " 4ms - bar",
423 " 2ms - baz",
424 " 2ms - ???",
425 ]
426 );
427 }
380} 428}