-
Notifications
You must be signed in to change notification settings - Fork 685
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
Possibly big performance improvement for time_zone::to_sys()
#817
Comments
Unfortunately the API of That being said, there are ways to optimize the performance within the current API. Let's start with this crude benchmark for #include "date/tz.h"
#include <chrono>
#include <iostream>
using D = std::chrono::system_clock::duration;
auto tz = date::current_zone();
extern date::sys_time<D> tp;
date::sys_time<D>
convert(date::local_time<D> tp_loc)
{
return tz->to_sys(tp_loc);
}
int
main()
{
using namespace std::chrono;
auto tp_start = system_clock::now();
auto tp_end = tp_start + 1s;
auto tp_loc = tz->to_local(tp_start);
std::uint64_t count = 0;
while (system_clock::now() < tp_end)
{
tp = convert(tp_loc);
tp_loc += 1s;
++count;
}
auto rate = count / ((tp_end - tp_start) / 1.s);
std::cout << rate << " conversions / sec\n";
}
date::sys_time<D> tp; For me, compiled with clang -O3, this yields about 707,000 conversions/sec. This is significantly slower than what you report, but is a good reference point anyway. If you can make the assumption that every local time has a unique mapping to UTC (i.e. exists and is not ambiguous), then a fairly simple change can be made to date::sys_time<D>
convert(date::local_time<D> tp_loc)
{
thread_local date::local_info info = tz->get_info(tp_loc);
date::sys_time<D> tp{tp_loc.time_since_epoch() - info.first.offset};
if (tp < info.first.begin || tp >= info.first.end)
{
info = tz->get_info(tp_loc);
tp = date::sys_time<D>{tp_loc.time_since_epoch() - info.first.offset};
}
return tp;
} This stores a For me this increases the performance to about 74.5 million conversions/sec (a speed up of about 100X). There are a couple of caveats:
This optimization, if it is acceptable in your application, has the potential to be even faster than the |
@HowardHinnant Thank you for your detailed response. |
There's something else going on here that I'm not completely understanding. Would you mind telling me what compiler/version you're using? That might be important. |
The compiler version info is as follows:
Given the size of the code base for the OLAP DBMS and the complexity of the query execution path, there could potentially be another factor contributing to this symptom. If that's the case, I apologize for any oversight. |
The OS info is as follows:
The OS might be too outdated to support the C++11 ABI. |
Ah! Do you know if you're using the old reference-counted string? Not sure, but that is probably Are you using the date lib flag |
Aside: Once you hit g++ 14 (which hasn't yet shipped), you'll be able to migrate off of this lib and use C++20 chrono. So whatever we do here, staying compatible with C++20 means you've got a path forward in the future. |
I use By the way, I ran my test on a CentOS 8 system a few minutes ago. It was fast without Thank you for your great and kind responses! |
Interesting! So can we conclude that the move from a ref-counted string to a short-short string optimization is the performance difference? |
Yes, I think the 'short string optimization' is the key. |
Hi,
Currently,
time_zone::to_sys()
eventually callstime_zone::load_sys_info()
.time_zone::load_sys_info()
buildssys_info
.While building, it copies
abbrev
std::string
intosys_info
.One
std::string
copy for onetime_zone::to_sys()
can significantly impact performance.In my case, in a big data processing system,
time_zone::to_sys()
was called at least 0.6 billion times for one query, and it took about 60 seconds to process the query. When I changed the data type ofabbrev
insys_info
struct fromstd::string
tostd::string_view
(thus avoiding the string copy), that query took only about 1 second.Although changing the data type of a public
struct
is a breaking change, in this case, the impact might not be severe, given that (as far as I understand) the lifetime of the backing store is infinite.Or perhaps there may be other solutions that can avoid the string copy.
(By the way, the source code version I use is somewhat outdated, but when I looked at the current code, it still copies the string.)
Thank you.
The text was updated successfully, but these errors were encountered: