在 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的值,你的代码没有用到
我有 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的值,你的代码没有用到