Skip to content

Significant performance degradation of Poco::DateTimeParser #4592

@tyler92

Description

@tyler92

Consider the following code:

#include <Poco/DateTimeFormat.h>
#include <Poco/DateTimeFormatter.h>
#include <Poco/DateTimeParser.h>
#include <stdexcept>

std::string toString(const Poco::DateTime& dt)
{
    return Poco::DateTimeFormatter::format(dt, Poco::DateTimeFormat::ISO8601_FRAC_FORMAT);
}

Poco::DateTime parsePoco(const std::string& text)
{
    int tzd = 0;
    const auto format = Poco::DateTimeFormat::ISO8601_FRAC_FORMAT;
    auto parsed = Poco::DateTimeParser::parse(format, text, tzd);
    parsed.makeUTC(tzd);
    return parsed;
}

void ASSERT_EQ(const std::string& a, const std::string& b)
{
    if (a != b)
    {
        throw std::runtime_error("Test FAILED");
    }
}

int main()
{
    for (int i = 0; i < 100'000; ++i)
    {
        auto parsed = parsePoco("2024-06-21T09:43:11.340159Z");
        ASSERT_EQ(toString(parsed), "2024-06-21T09:43:11.340159Z");

        parsed = parsePoco("2024-06-21T09:43:11.340159+07:00");
        ASSERT_EQ(toString(parsed), "2024-06-21T02:43:11.340159Z");
    }

    return 0;
}

Execution time (Release configuration):

Poco 1.12.5:    96 ms
Poco 1.13.3: 17179 ms

With the format Poco::DateTimeFormat::ISO8601_FRAC_FORMAT + " " (with an additional space) execution time becomes better for 1.13.3.

I guess the reason is the following commit: 4f1cf68 (#4330).

Up to 8 regex expressions are compiled on each call

for (const auto& f : REGEX_LIST)
{
if (RegularExpression(*f).match(dateTime)) return true;
}

if the provided format is known:

if (fmt.empty() || str.empty() || (DateTimeFormat::hasFormat(fmt) && !DateTimeFormat::isValid(str)))

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions