-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Improve Debug impl of time::Duration
#50364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve Debug impl of time::Duration
#50364
Conversation
|
r? @KodrAus (rust_highfive has picked a reviewer for you, use r? to override) |
|
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
9a73c63 to
73c40c3
Compare
Debug imps of time::DurationDebug impl of time::Duration
|
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
|
Failure caused by warnings in some of the tests I moved. So yeah, apparently those tests weren't executed in quite some time... Hopefully those tests are fixed now. |
|
I checked the different formatting options that this impl could respect, but I concluded that most are not worth it. When was the last time you specified any formatting options while using
So, I just implemented the |
Debug impl of time::DurationDebug impl of time::Duration
|
☔ The latest upstream changes (presumably #50466) made this pull request unmergeable. Please resolve the merge conflicts. |
Prior to this, Duration simply derived Debug. Since Duration doesn't
implement `Display`, the only way to inspect its value is to use
`Debug`. Unfortunately, the derived `Debug` impl is far from optimal
for humans. In many cases, Durations are used for some quick'n'dirty
benchmarking (or in general: measuring the time of some code). Correctly
understanding the output of Duration's Debug impl is not easy (e.g.
is "{ secs: 0, nanos: 968360102 }" or "{ secs: 0, nanos 98507324 }"
shorter?).
This commit replaces the derived impl with a manual one. It prints
the duration as seconds (i.e. "3.1803s") if the duration is longer than
a second, otherwise it prints it in either ms, µs or ns (depending on
the duration's length). This already helps readability a lot and it
never omits information that is stored.
This `Debug` impl does *not* respect the following formatting parameters:
- fill/align/padding: difficult to implement, probably not worth it
- alternate # flag: not clear what this should do
25d3d4b to
9eeb13f
Compare
Should be ready now ^_^ |
|
I would like to do a critic about this feature:
I see two solution to my concern:
|
|
Summary: I don't quite care whether or not this becomes a My reasoning for implementing I assumed the
This requirement doesn't sound too strict. However, it's still not clear what "user-facing output" for About There are a number of other
So |
|
You said
I could answer you with your own sentence (just need to inverse it):
I agree with you about "faithfully" but the sentence clearly say "as possible". I think it's possible to be more accurate about the internal state of Duration than your new implementation as I show it in my previous exemple And your exemple with
I really like your output as a user of Your new implementation look nice enough for me to be a good candidate to |
|
I'll dig into the source shortly, but just thought I'd leave a note now to say I'm in favour of this clearer |
|
Ping from triage @KodrAus! You need to complete your review! |
src/libcore/tests/time.rs
Outdated
| assert_eq!(format!("{:.2?}", Duration::new(0, 1_000)), "1.00µs"); | ||
| assert_eq!(format!("{:.2?}", Duration::new(0, 7_001)), "7.00µs"); | ||
| assert_eq!(format!("{:.2?}", Duration::new(0, 7_100)), "7.10µs"); | ||
| assert_eq!(format!("{:.2?}", Duration::new(0, 1_999)), "1.99µs"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, the precision here is a bit inconsistent with floating points, that will also perform rounding through its unholy rendering machinery. For instance:
assert_eq!("2.00", format!("{:.2}", 1.995f32));We might want to consider rounding here too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! I just pushed a commit which adds correct rounding like floats do. I also pushed a commit which fixes the behavior for a precision > 9.
Rounding is done like for printing floating point numbers. If the first digit which isn't printed (due to the precision parameter) is larger than '4', the number is rounded up.
Previously, the code would panic for high precision values. Now it has the same behavior as printing normal floating point values: if a high precision is specified, '0's are added.
|
Can we get a crater run for this? Last time we changed the debug output there were some regressions (some crates assumes the debug output is guaranteed not to change, it would be nice to alert the authors). |
|
cc @rust-lang/infra |
|
@bors try |
|
⌛ Trying commit 59e7114 with merge 68967b5e9d4ec8c0ad4f402e6bf624995b499cdf... |
|
Crater started. |
|
Hi myself and @KodrAus! Crater results are at: http://cargobomb-reports.s3.amazonaws.com/pr-50364/index.html. 'Blacklisted' crates (spurious failures etc) can be found here. If you see any spurious failures not on the list, please make a PR against that file. (interested observers: Crater is a tool for testing the impact of changes on the crates.io ecosystem. You can find out more at the repo if you're curious) |
|
I quickly scanned the crater results and none of the 7 regressions look like they are caused by this change. |
|
This looks good to me! @bors r+ |
|
📌 Commit 59e7114 has been approved by |
|
Thanks again for working on this @LukasKalbertodt! |
|
⌛ Testing commit 59e7114 with merge 85e8e0f19506d467f478c8d2f66f508de021e4db... |
|
💔 Test failed - status-travis |
|
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
1 similar comment
|
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
|
⌛ Testing commit 59e7114 with merge 8d7c0ed49df2d0deabe6e737f4ffdaefd5ed983b... |
…=KodrAus
Improve `Debug` impl of `time::Duration`
Hi there!
For a long time now, I was getting annoyed by the derived `Debug` impl of `Duration`. Usually, I use `Duration` to either do quick'n'dirty benchmarking or measuring the time of some operation in general. The output of the derived Debug impl is hard to parse for humans: is { secs: 0, nanos: 968360102 } or { secs: 0, nanos 98507324 } longer?
So after running into the annoyance several times (sometimes building my own function to print the Duration properly), I decided to tackle this. Now the output looks like this:
```
Duration::new(1, 0) => 1s
Duration::new(1, 1) => 1.000000001s
Duration::new(1, 300) => 1.0000003s
Duration::new(1, 4000) => 1.000004s
Duration::new(1, 600000) => 1.0006s
Duration::new(1, 7000000) => 1.007s
Duration::new(0, 0) => 0ns
Duration::new(0, 1) => 1ns
Duration::new(0, 300) => 300ns
Duration::new(0, 4001) => 4.001µs
Duration::new(0, 600300) => 600.3µs
Duration::new(0, 7000000) => 7ms
```
Note that I implemented the formatting manually and didn't use floats. No information is "lost" when printing. So `Duration::new(123_456_789_000, 900_000_001)` prints as `123456789000.900000001s`.
~~This is not yet finished~~, but I wanted to open the PR now already in order to get some feedback (maybe everyone likes the derived impl).
### Still ToDo:
- [x] Respect precision ~~and width~~ parameter of the formatter (see [this comment](#50364 (comment)))
### Alternatives/Decisions
- Should large durations displayed in minutes, hours, days, ...? For now, I decided not to because the current formatting is close the how a `Duration` is stored. From this new `Debug` output, you can still easily see what the values of `secs` and `nanos` are. A formatting like `3h 27m 12s 9ms` might be more appropriate for a `Display` impl?
- Should this rather be a `Display` impl and should `Debug` be derived? Maybe this formatting is too fancy for `Debug`? In my opinion it's not and, as already mentioned, from the current format one can still very easily determine the values for `secs` and `nanos`.
- Whitespace between the number and the unit?
### Notes for reviewers
- ~~The combined diff sucks. Rather review both commits individually.~~
- ~~In the unit test, I am building my own type implementing `fmt::Write` to test the output. Maybe there is already something like that which I can use?~~
- My `Debug` impl block is marked as `#[stable(...)]`... but that's fine since the derived Debug impl was stable already, right?
---
~~Apart from the main change, I moved all `time` unit tests into the `tests` directory. All other `libcore` tests are there, so I guess it was simply an oversight. Prior to this change, the `time` tests weren't run, so I guess this is kind of a bug fix. If my `Debug` impl is rejected, I can of course just send the fix as PR.~~ (this was already merged in #50466)
|
☀️ Test successful - status-appveyor, status-travis |
|
Thanks for including precision! For a real duration, I'd always rather |
|
Thank you for this! It's always nice when updating my compiler gives me prettier debug logging for free! |
Hi there!
For a long time now, I was getting annoyed by the derived
Debugimpl ofDuration. Usually, I useDurationto either do quick'n'dirty benchmarking or measuring the time of some operation in general. The output of the derived Debug impl is hard to parse for humans: is { secs: 0, nanos: 968360102 } or { secs: 0, nanos 98507324 } longer?So after running into the annoyance several times (sometimes building my own function to print the Duration properly), I decided to tackle this. Now the output looks like this:
Note that I implemented the formatting manually and didn't use floats. No information is "lost" when printing. So
Duration::new(123_456_789_000, 900_000_001)prints as123456789000.900000001s.This is not yet finished, but I wanted to open the PR now already in order to get some feedback (maybe everyone likes the derived impl).Still ToDo:
and widthparameter of the formatter (see this comment)Alternatives/Decisions
Durationis stored. From this newDebugoutput, you can still easily see what the values ofsecsandnanosare. A formatting like3h 27m 12s 9msmight be more appropriate for aDisplayimpl?Displayimpl and shouldDebugbe derived? Maybe this formatting is too fancy forDebug? In my opinion it's not and, as already mentioned, from the current format one can still very easily determine the values forsecsandnanos.Notes for reviewers
The combined diff sucks. Rather review both commits individually.In the unit test, I am building my own type implementingfmt::Writeto test the output. Maybe there is already something like that which I can use?Debugimpl block is marked as#[stable(...)]... but that's fine since the derived Debug impl was stable already, right?Apart from the main change, I moved all(this was already merged in #50466)timeunit tests into thetestsdirectory. All otherlibcoretests are there, so I guess it was simply an oversight. Prior to this change, thetimetests weren't run, so I guess this is kind of a bug fix. If myDebugimpl is rejected, I can of course just send the fix as PR.