-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
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::Duration
Debug
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::Duration
Debug
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
Debug
impl ofDuration
. Usually, I useDuration
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:
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
Duration
is stored. From this newDebug
output, you can still easily see what the values ofsecs
andnanos
are. A formatting like3h 27m 12s 9ms
might be more appropriate for aDisplay
impl?Display
impl and shouldDebug
be 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 forsecs
andnanos
.Notes for reviewers
The combined diff sucks. Rather review both commits individually.In the unit test, I am building my own type implementingfmt::Write
to test the output. Maybe there is already something like that which I can use?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(this was already merged in #50466)time
unit tests into thetests
directory. All otherlibcore
tests are there, so I guess it was simply an oversight. Prior to this change, thetime
tests weren't run, so I guess this is kind of a bug fix. If myDebug
impl is rejected, I can of course just send the fix as PR.