在 C/C++ 中解析 100,000 个 YYYYMMDD.HHMMSS 字符串时 mktime 变慢

Slow mktime when parsing 100,000 YYYYMMDD.HHMMSS strings in C/C++

我有 100,000 个 std::strings,格式为 YYYYMMDD.HHMMSS,例如。 “20160621.213500”,我需要用一些值解析和填充结构,包括纪元时间戳。

它运行非常缓慢,罪魁祸首是对 mktime 的调用。有什么替代方法可以加快速度吗?

#define STRNCPY(dest, src, len) \
    { memcpy((dest), (src), (len)) ; dest[(len)] = '[=12=]'; }

void
DvStorUtils::parseDateTimeString(const char *dateTimeStr, TDateTime &dateTime)
{
    // New, C-Style implementation
    strcpy(dateTime.dateTimeStr, dateTimeStr);

    char buf[32];
    STRNCPY(buf, dateTimeStr,    4);  dateTime.year   = atoi(buf);
    STRNCPY(buf, dateTimeStr+ 4, 2);  dateTime.month  = atoi(buf);
    STRNCPY(buf, dateTimeStr+ 6, 2);  dateTime.day    = atoi(buf);
    STRNCPY(buf, dateTimeStr+ 9, 2);  dateTime.hour   = atoi(buf);
    STRNCPY(buf, dateTimeStr+11, 2);  dateTime.minute = atoi(buf);
    STRNCPY(buf, dateTimeStr+13, 2);  dateTime.second = atoi(buf);


    struct tm tmStruct;
    tmStruct.tm_year = dateTime.year - 1900;
    tmStruct.tm_mon  = dateTime.month-1;
    tmStruct.tm_mday = dateTime.day;
    tmStruct.tm_hour = dateTime.hour;
    tmStruct.tm_min  = dateTime.minute;
    tmStruct.tm_sec  = dateTime.second;

    dateTime.totalSecElapsed = mktime(&tmStruct);
}

Jeremy 的想法是对的——mktime 非常非常慢。

注释掉mktime,瞬间处理10万行。即使打印出每一行。将其放回原处,大约需要一分钟才能完成。

我用缓存实现替换了 mktime libfast-mktime,它几乎和完全没有 mktime 一样快。

memoized libfast-mktime 在这里效果很好,因为每一行在时间上都非常接近它之前的行。

要加快此 mktime 函数的速度,只需像这样设置 TZ 系统值:

  • env TZ=PST8PDT
  • 导出 TZ=PST8PDT

而且它会很快工作,因为每次转义都会得到时区

如果您只需要来自 tm 结构的 time_t 值,那么您可以为它编写一个自定义函数。多出来的时间可能是因为mktime还填入了tm_wday和tm_yday的值,你的代码没有用到