I guess in C++, one has to have experts explain to you why something is good or bad, because it's not immediately apparent to the average programmer. Take that for what you will. The talk is excellent though. Baby steps and very clearly explained.
This appears to be a reoccurring pattern in C++ when introduced to new features & libs. First reaction is often "why would I?", but it usually ends with "how would I without?".
I had no idea was so straightforward! Every time I had seen it used, I got spooked by the long type names, but now I see it’s not that complicated to use! And an absolutely fantastic talk as well! It certainly is a great skill to make this much information easily digestible.
"Every time I had seen it used, I got spooked by the long type names" That's the entirety of C++ for me lmao. "Oh, you missed a `const` while daring to use a STL type? Have three kilobytes of error messages with completely indecipherable types". Thanks GCC.
I'm pretty sure people would've done that by now, it'd be so cool to just do something like Weights::Kilogram potatoes(5kg); if (potatoes >= 800g) { cout
@@VivekYadav-ds8oz There's a few libraries for that... I've tried this one and I have mixed feelings but overall it was pretty good. github.com/nholthaus/units
Nice talk. It is mainly 2 parts: part 1, duraton: what duration is and what is under the hood and how much it cost (the same as builtin types) how to convert (self-defined) durations and how it works warn us when to use duration_cast, accuracy loss part 2, time point and clock: what is time point and time point operations, relation with duration -- tp +- tp => duration, tp +- duration => tp what is clocks, how they generate time point.
The epoch change for system_clock announced by VS in the Q&A period of this talk has been rescinded. And the C++20 draft spec now specifies the system_clock epoch to existing practice (1970) so that it can be officially depended upon.
@@williamchamberlain2263 Well its really an Earth solar time coordinate. I would prefer they use international atomic time for system clocks and convert to UTC in software.It would allow better handling of leap seconds.Though I forget how it would effect handling of GPSS time but that is a pretty narrow case.
Good I am so tired of MS breaking standards to purposefully harm portability and increase vendor lock in. I know average home users fall for such shenanigans but I'm glad they get push back from the other end.
Thanks, but I rarely have a need for those things. I did however use std::chrono and std::thread to quickly make a real-time terminal game prototype. I absolutely love having the ability to typedef custom durations :)
I can only imagine how great a Boost.Units replacement based on the chrono library would be. But for now I'm looking forward to getting a standard datetime library.
At about 50:30, wouldn't it induce an error if we chose a duration type where the Fraction is too large, like hours, because the implicit conversion might be lossy, depending on the implementation of C++?
If the conversion is to a duration with a floating-point rep, then you can get round-off (precision) error, but not truncation error. For example if you are converting integral nanoseconds to floating-point hours, it will first convert the nanoseconds to the floating point type, then divide by 3.6e+12. If you are converting to integral hours, there will be a truncation error (as integer division does), and you will have to use duration_cast to explicitly ask for such a truncating conversion. I.e. it will take the number of nanoseconds and divide by 3'600'000'000'000.
I might be able to help with that. ;-) I meant that `cout` is legacy with respect to ``. `` was introduced in C++11, whereas `cout` was introduced in C++98. So naturally `cout` knows nothing about ``. I hope to teach `` about `cout` in a future standard (wg21.link/p0355), and you can experiment with that today if you like (github.com/HowardHinnant/date). But my main point in the presentation is that you can interface with any legacy code (code which was not designed to work with ``) by using the `.count()` member function of durations.
Ah, thanks for clearing that up! And thanks for the great talk. I was able to clean up the timing code in my personal project quite a bit after learning how is really supposed to be used.
So if I'm stuck in a C++2011/2014 project, how can I use chrono to calculate the number of months between two time points? It's not as simple as using 30 days or 2628000 seconds because it really depends on WHICH months are between the two time points.
I wanna ask an error I getting while using chrono::high_resolution_clock::time_point tstart, tstop; then tstart = chrono::high_resolution_clock::now; but I get the error "No operator "=" matches these operands. Operand types are std::chrono::steady_clock::time_point = std::chrono::steady_clock::time_point ()"
Is there a way to use chrono and exceed the defacto ranges? Ie, can you easily, neatly, and portably create a Nanoseconds duration capable of >146 /292 years
Yes. Use a bigger number. For example if your platform has a 128 bit integer, you can use that as the rep in duration. Otherwise you can get a 128 bit emulator from libraries such as boost::multiprecision and use that in duration.
When he says "in all 3 implementations they are the same thing" at 48:25 . Is the 3 refering to gcc, clang and msvc and their implementaitons of c++ std lib?
Um... What? What does he mean when he talks about a million-element vector not initializing every element to zero? Any standard container _will_ forcefully value-initialize all of its elements, regardless of whether you asked it to or not. And for an object with a defaulted default constructor, it will involve zeroing everything out (at least). You can't prevent it unless you customize the allocator.
Nice talk. Starts with a lie in the first minute: the "using namespace std::chrono" is not just saving space: the notation "5s" does not work without it.
I'm so used with convoluted date's library from other languages(I'm speaking of you javascript) . That I struggled with std::chrono trying to make things complicated without any reason. It's pretty straight forward, duration_cast it's being handy in my implementations.
You can convert a year, month and day to a system_clock-based time_point with: sys_days tp = year{y}/m/d; where y, m and d have type int. sys_days is a type alias for time_point, aka a time_point with days precision based on system_clock. If you want a finer precision time_point, say system_clock::time_point you can: system_clock::time_point tp = sys_days{year{y}/m/d}; tp will point to 00:00:00.000000 UTC of that year, month and day.
Unnumbered (why?) slide at 3:30: he claims that seconds has an int internally. Did this change to float? I can "3.14 * 3s" and the "count" is 9.42. See also 12:20. EDIT. Ah. He later admits that that was a white lie. After 50:00 there is a lot of missing information. (I hate how he keeps saying "just" and "simply". Unless I exactly type his examples I get a ton of compilation errors. It is not at all clear how this stuff generalizes.) Why can you "nanoseconds{t1-t0}" but you have to cast to get anything else?
> Why can you "nanoseconds{t1-t0}" but you have to cast to get anything else? Because t1 and t0 have nanosecond precision. "Everything else" is coarser than nanoseconds, assuming integral representation. So the library doesn't let you loose information implicitly. To truncate nanoseconds to microseconds (for example), you have to use a named conversion since it is a lossy conversion. Going the other way, microseconds to nanoseconds, is loss-less. And that can happen implicitly.
Because in C++11/14/17 cout and the rest of the streaming library is unaware of chrono. I.e. one can't stream out chrono types/values. This changes in C++20. Now you can stream out chrono types. This eliminates a large part of the need for the duration member function .count().
I mean, if you really need to get the time since unix epoch in seconds that often you can just create a function for that. auto now() -> std::chrono::seconds { using namespace std::chrono; // Purposely not calling .count to avoid defeating the purpose of the library return duration_cast(system_clock::now().time_since_epoch()); } Btw, time(nullptr) *is* confusing. You have to lookup documentation in order to know the units it returns. Also, I can't find the rationale behind the function having an out param and also a return value for the same thing.
@@kebien6020 "You have to lookup documentation in order to know..." Yeah, you have to lookup the documentation in order to know how it works. You are pretending like you don't have to do this with chrono as well (or with literally every single concept in programming).
I was just rewatching this, and voilà: #include #include using namespace std::literals::chrono_literals; void f(std::chrono::milliseconds d) { std::cout
One can increase range either by reducing precision (e.g. use microseconds instead of nanoseconds), or by changing the rep to something with a larger range (e.g. __int128). I'm sure astrophysicists are familiar with such tradeoffs in their computations, with or without chrono.
@@howardhinnant OK, let's just say that an astrophysicist might use an implementation where the range of SECONDS is as large as desired, or else use a custom duration...
I used to think was okay. It's clearly better than okay.
Took me a while to got used to it, but i'm now a believer.
I guess in C++, one has to have experts explain to you why something is good or bad, because it's not immediately apparent to the average programmer. Take that for what you will.
The talk is excellent though. Baby steps and very clearly explained.
This appears to be a reoccurring pattern in C++ when introduced to new features & libs. First reaction is often "why would I?", but it usually ends with "how would I without?".
@Mel FloranceAt first glance, yea))
I feel like they've forgot what "KISS" means. It's getting better by c++20, but still 😕
I had no idea was so straightforward!
Every time I had seen it used, I got spooked by the long type names, but now I see it’s not that complicated to use!
And an absolutely fantastic talk as well! It certainly is a great skill to make this much information easily digestible.
Very pleased that the tutorial was so helpful.
"Every time I had seen it used, I got spooked by the long type names"
That's the entirety of C++ for me lmao. "Oh, you missed a `const` while daring to use a STL type? Have three kilobytes of error messages with completely indecipherable types". Thanks GCC.
chrono is one of the best things in recent C++ progress, which makes life much easier.
Hands down, the best library tutorial I have ever seen.
Before watching this video, I never thought chrono is so good. It would be great if there is similar implementation for Si Units.
I'm pretty sure people would've done that by now, it'd be so cool to just do something like
Weights::Kilogram potatoes(5kg);
if (potatoes >= 800g)
{
cout
@@VivekYadav-ds8oz There's a few libraries for that... I've tried this one and I have mixed feelings but overall it was pretty good. github.com/nholthaus/units
Never thought talking about seconds could be so interesting
This might the best presentation title I've ever seen. "It's about time" is just awesome!
Nice talk.
It is mainly 2 parts:
part 1, duraton:
what duration is and what is under the hood and how much it cost (the same as builtin types)
how to convert (self-defined) durations and how it works
warn us when to use duration_cast, accuracy loss
part 2, time point and clock:
what is time point and time point operations, relation with duration -- tp +- tp => duration, tp +- duration => tp
what is clocks, how they generate time point.
The epoch change for system_clock announced by VS in the Q&A period of this talk has been rescinded. And the C++20 draft spec now specifies the system_clock epoch to existing practice (1970) so that it can be officially depended upon.
Thanks for the update! Good that UTC really is U.
@@williamchamberlain2263 Well its really an Earth solar time coordinate. I would prefer they use international atomic time for system clocks and convert to UTC in software.It would allow better handling of leap seconds.Though I forget how it would effect handling of GPSS time but that is a pretty narrow case.
Good I am so tired of MS breaking standards to purposefully harm portability and increase vendor lock in. I know average home users fall for such shenanigans but I'm glad they get push back from the other end.
UTC, atomic, and GPS clocks where added in C++20.
This talk was simply remarkable! Thank you Howard for this amazing presentation!
The best tutorial on Chrono.
The explanation of the chrono library is so beautifully done, Thanks❤
A really comprehensive "chrono" tutorial. Going to bookmark this.
I am going to look for all sorts of excuses to use chrono now. This is great! :)
Here is a way to make chrono so much more useful by extending it to calendars and timezones: github.com/HowardHinnant/date
Thanks, but I rarely have a need for those things. I did however use std::chrono and std::thread to quickly make a real-time terminal game prototype. I absolutely love having the ability to typedef custom durations :)
This was very helpful, I was struggling through error codes and stack overflow answers that didn’t quite line up to what I needed. Thanks!!
I can only imagine how great a Boost.Units replacement based on the chrono library would be. But for now I'm looking forward to getting a standard datetime library.
Proper value objects & libraries _would_ be nice.
At about 50:30, wouldn't it induce an error if we chose a duration type where the Fraction is too large, like hours, because the implicit conversion might be lossy, depending on the implementation of C++?
If the conversion is to a duration with a floating-point rep, then you can get round-off (precision) error, but not truncation error. For example if you are converting integral nanoseconds to floating-point hours, it will first convert the nanoseconds to the floating point type, then divide by 3.6e+12. If you are converting to integral hours, there will be a truncation error (as integer division does), and you will have to use duration_cast to explicitly ask for such a truncating conversion. I.e. it will take the number of nanoseconds and divide by 3'600'000'000'000.
At 20:42, Howard says that cout is legacy code. Does anyone know what he means by this? A quick google search didn't help
I might be able to help with that. ;-) I meant that `cout` is legacy with respect to ``. `` was introduced in C++11, whereas `cout` was introduced in C++98. So naturally `cout` knows nothing about ``. I hope to teach `` about `cout` in a future standard (wg21.link/p0355), and you can experiment with that today if you like (github.com/HowardHinnant/date).
But my main point in the presentation is that you can interface with any legacy code (code which was not designed to work with ``) by using the `.count()` member function of durations.
Ah, thanks for clearing that up! And thanks for the great talk. I was able to clean up the timing code in my personal project quite a bit after learning how is really supposed to be used.
So if I'm stuck in a C++2011/2014 project, how can I use chrono to calculate the number of months between two time points? It's not as simple as using 30 days or 2628000 seconds because it really depends on WHICH months are between the two time points.
You can use my date.h library to calculate the number of months between two time points in C++11/14/17.
I LITERALLY just saw this dude on stack overflow.
Did I forget to turn off my webcam again?! ;-)
I wanna ask an error I getting while using
chrono::high_resolution_clock::time_point tstart, tstop;
then
tstart = chrono::high_resolution_clock::now;
but I get the error "No operator "=" matches these operands. Operand types are std::chrono::steady_clock::time_point = std::chrono::steady_clock::time_point ()"
Yeah it's a stupid typo, I cry every time I see this thread.
Anyone who tells you they've never made a stupid coding error is either a liar or has never coded. :-)
Is there a way to use chrono and exceed the defacto ranges? Ie, can you easily, neatly, and portably create a Nanoseconds duration capable of >146 /292 years
Yes. Use a bigger number. For example if your platform has a 128 bit integer, you can use that as the rep in duration. Otherwise you can get a 128 bit emulator from libraries such as boost::multiprecision and use that in duration.
Is platform independent????
Want it to work on both windows and linux systems.
is portable C++. It works on Windows, Linux, macOS, Android, iOS ... anywhere you can target with a modern C++ compiler.
This is such an amazing library.
std::vector does value initialise it's elements. Therefore it will zero a vector of std::chrono::second or anything else by default.
When he says "in all 3 implementations they are the same thing" at 48:25 . Is the 3 refering to gcc, clang and msvc and their implementaitons of c++ std lib?
Yes.
@@howardhinnant Thank you, great presentation 🙂!
Um... What? What does he mean when he talks about a million-element vector not initializing every element to zero? Any standard container _will_ forcefully value-initialize all of its elements, regardless of whether you asked it to or not. And for an object with a defaulted default constructor, it will involve zeroing everything out (at least). You can't prevent it unless you customize the allocator.
Nice talk. Starts with a lie in the first minute: the "using namespace std::chrono" is not just saving space: the notation "5s" does not work without it.
Wow! It's really a great header and even better video about it. Kudos!!
I'm so used with convoluted date's library from other languages(I'm speaking of you javascript) . That I struggled with std::chrono trying to make things complicated without any reason. It's pretty straight forward, duration_cast it's being handy in my implementations.
How can i assign a custom year, month and day to a time_point?
You can convert a year, month and day to a system_clock-based time_point with: sys_days tp = year{y}/m/d; where y, m and d have type int. sys_days is a type alias for time_point, aka a time_point with days precision based on system_clock. If you want a finer precision time_point, say system_clock::time_point you can: system_clock::time_point tp = sys_days{year{y}/m/d}; tp will point to 00:00:00.000000 UTC of that year, month and day.
One thing i would want is that the output stream operator
You may find this free, open-source, header-only library useful: howardhinnant.github.io/date/chrono_io.html
Localized, of course ...
A well-designed library.. Thank you
Interestingly, time points and durations are analogous to affine space and vector space.
C++ libraries like std::chrono are the biggest argument for C++ against C. All the safeties and convenience without any loss of performance.
Just one question though, why is it named "chrono" ?
Chrono is abbreviation of word chronology. For further reading en.wikipedia.org/wiki/Chronology
@@rarRoarrar Not sure Chronos was a titan. You may confuse him with the titan Cronos, father of Zeus.
@@Aither- Chronos and Cronus were one and the same for like 2000 years.
very good speech, thank you
I would love to see a codebase that overflows chrono::seconds::max() :D
Unnumbered (why?) slide at 3:30: he claims that seconds has an int internally. Did this change to float? I can "3.14 * 3s" and the "count" is 9.42. See also 12:20.
EDIT. Ah. He later admits that that was a white lie.
After 50:00 there is a lot of missing information. (I hate how he keeps saying "just" and "simply". Unless I exactly type his examples I get a ton of compilation errors. It is not at all clear how this stuff generalizes.) Why can you "nanoseconds{t1-t0}" but you have to cast to get anything else?
> Why can you "nanoseconds{t1-t0}" but you have to cast to get anything else?
Because t1 and t0 have nanosecond precision. "Everything else" is coarser than nanoseconds, assuming integral representation. So the library doesn't let you loose information implicitly. To truncate nanoseconds to microseconds (for example), you have to use a named conversion since it is a lossy conversion. Going the other way, microseconds to nanoseconds, is loss-less. And that can happen implicitly.
Why does he say cout is legacy code? Is there an alternative?
Because in C++11/14/17 cout and the rest of the streaming library is unaware of chrono. I.e. one can't stream out chrono types/values. This changes in C++20. Now you can stream out chrono types. This eliminates a large part of the need for the duration member function .count().
Before watching this talk I use lots of .count(), duration_cast and high_resolution_clock
33:29 isn't it "Instantiation" and not "specialization"?
one problem is that is too difficult to convert durations from string or to string.
We hope to address that in C++20. Not only with durations, but time_points as well.
Helpful tips in that video!
Can a man be this clear?
I laughed when he introduced duration_cast. That's so standard library!
allows to to replace confusing code like:
time(nullptr)
with:
std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()
I mean, if you really need to get the time since unix epoch in seconds that often you can just create a function for that.
auto now() -> std::chrono::seconds
{
using namespace std::chrono;
// Purposely not calling .count to avoid defeating the purpose of the library
return duration_cast(system_clock::now().time_since_epoch());
}
Btw, time(nullptr) *is* confusing. You have to lookup documentation in order to know the units it returns. Also, I can't find the rationale behind the function having an out param and also a return value for the same thing.
@@kebien6020 the worst documentation I've ever seen in terms of clarity is chrono's
@@kebien6020 "You have to lookup documentation in order to know..." Yeah, you have to lookup the documentation in order to know how it works. You are pretending like you don't have to do this with chrono as well (or with literally every single concept in programming).
excellent!
Time a function 49:56
I was just rewatching this, and voilà:
#include
#include
using namespace std::literals::chrono_literals;
void f(std::chrono::milliseconds d) {
std::cout
"If you overflow, you've got issues." I suppose that astrophysicists may be mildly offended by this line...
One can increase range either by reducing precision (e.g. use microseconds instead of nanoseconds), or by changing the rep to something with a larger range (e.g. __int128). I'm sure astrophysicists are familiar with such tradeoffs in their computations, with or without chrono.
@@howardhinnant OK, let's just say that an astrophysicist might use an implementation where the range of SECONDS is as large as desired, or else use a custom duration...
@@howardhinnant Just to clarify matters, I don't at all dislike chrono, to the contrary, I think it's fine work.
Chrono made game programming simpler
I really like the path that STL takes since c++11, but this chrono thing is the single (and maybe only) part of it, that is straight up sh*t
Too long
Over engineered and the problem overrated. Never had an issue dealing with time in other toolkits like Qt.