boostorg / boostorg/date_time

construction of input facet is slow, e.g., local_time_input_facet

Open
#177 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
70
Forks
99
PR merge metrics
No merged PRs in 30d

Description

I noticed a significant performance difference in the following two approaches, when a facet is created for every parsing and when it's re-used. It turned out, that the latter is 100 times faster. It means, that e.g. to parse 100 000 entries, it can take around half of a minute vs a third part of a second.
A profiler shows that construction of `string_parse_tree` is the reason of the slowness.

Slow:
```C++
void naive_parsing(uint32_t iterations = k_count)
{
for (uint32_t i = 0; i < iterations; ++i)
{
local_date_time ldt(not_a_date_time);
local_time_input_facet* input_facet = new local_time_input_facet();
input_facet->format("%Y-%m-%dT%H:%M:%s%Q");
std::stringstream ss{k_input};
ss.imbue(std::locale(ss.getloc(), input_facet));
ss >> ldt;
auto unix_time = (ldt.utc_time() - time_t_epoch).total_milliseconds();
if (k_expected_unix_time != unix_time)
{
std::abort();
}
}
}
```
Faster:
```C++
void sstream_cached_parsing()
{
local_time_input_facet* input_facet = new local_time_input_facet();
std::stringstream ss;
ss.imbue(std::locale(ss.getloc(), input_facet));
input_facet->format("%Y-%m-%dT%H:%M:%s%Q");
for (uint32_t i = 0; i < k_count; ++i)
{
local_date_time ldt(not_a_date_time);
ss.clear();
ss.str(k_input);
ss >> ldt;
auto unix_time = (ldt.utc_time() - time_t_epoch).total_milliseconds();
if (k_expected_unix_time != unix_time)
{
std::abort();
}
}
}
```
FWIW, in the latter case, the performance is comparable with the same naive approach but based on https://github.com/HowardHinnant/date.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.