1、背景
项目中使用发现mktime开销较大,使用性能测试工具测试一下;
2、接口说明
主要用于所指向的结构转换为自 1970 年1月1日以来持续时间的秒数,发生错误时返回-1。
SYNOPSIS top
#include <time.h>
time_t mktime(struct tm *timeptr);
DESCRIPTION
The functionality described on this reference page is aligned
with the ISO C standard. Any conflict between the requirements
described here and the ISO C standard is unintentional. This
volume of POSIX.1‐2017 defers to the ISO C standard.
The mktime() function shall convert the broken-down time,
expressed as local time, in the structure pointed to by timeptr,
into a time since the Epoch value with the same encoding as that
of the values returned by time(). The original values of the
tm_wday and tm_yday components of the structure shall be ignored,
and the original values of the other components shall not be
restricted to the ranges described in <time.h>.
---
Broken-down time is stored in the structure tm, which is defined in <time.h> as follows:
struct tm {
int tm_sec; /* Seconds (0-60) */
int tm_min; /* Minutes (0-59) */
int tm_hour; /* Hours (0-23) */
int tm_mday; /* Day of the month (1-31) */
int tm_mon; /* Month (0-11) */
int tm_year; /* Year - 1900 */
int tm_wday; /* Day of the week (0-6, Sunday = 0) */
int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */
int tm_isdst; /* Daylight saving time */
};
网上查了一些资料,这篇文章通过源码分析得出结论:
《mktime性能分析》
从mktime的源码实现中可以看出,mktime的大致执行流程如下:
首先通过调用__tzset()对时区进行设置
若TZ环境变量为NULL,尝试调用__tzfile_read读取文件中的时区信息
只需要首次设置,若改变或为NULL重新设置
然后调用__mktime_internal进行时间转换
检查系统的tm_isdst(是否为夏令时)和传入的struct tm的tm_isdst,若两个不一致(isdst_differ),则进行矫正tm_isdst
从上源码可以得出结论:
影响mktime性能的两个因素主要包括两方面:
一是TZ设置是否为NULL,
二是传入的struct tm参数的tm_isdst成员与系统的是否一致。
3、性能测试
结合另一篇文章的思路 《mktime性能测试》
使用Google-benchmark框架自己再实现一下,首先实现基础类:
#include <time.h>
#include <sys/time.h>
#include <assert.h>
#include <benchmark/benchmark.h>
class bm_mktime:
public ::benchmark::Fixture
{
public:
time_t _now;
struct tm _tm;
bm_mktime()
{
setenv("TZ", "", 0);
setenv("TZ", "Asia/Shanghai", 0);