1、背景

项目中使用发现mktime开销较大,使用性能测试工具测试一下;

2、接口说明

主要用于所指向的结构转换为自 1970 年1月1日以来持续时间的秒数,发生错误时返回-1。

SYNOPSIS         top#include <time.h>time_t mktime(struct tm *timeptr);
DESCRIPTIONThe functionality described on this reference page is alignedwith the ISO C standard. Any conflict between the requirementsdescribed here and the ISO C standard is unintentional. Thisvolume 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 thatof the values returned by time().  The original values of thetm_wday and tm_yday components of the structure shall be ignored,and the original values of the other components shall not berestricted 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);unsetenv("TZ");}void SetUp(const ::benchmark::State &st){_now = time(NULL);(void)localtime_r(&_now, &_tm);}void TearDown(const ::benchmark::State &){}
};

localtime接口测试

//
// localtime
//
BENCHMARK_DEFINE_F(bm_mktime, localtime_TZ_null)(benchmark::State &state)
{unsetenv("TZ");for (auto _ : state) {benchmark::DoNotOptimize(localtime(&_now));}
}BENCHMARK_DEFINE_F(bm_mktime, localtime_TZ_empty)(benchmark::State &state)
{setenv("TZ", "", 0);for (auto _ : state) {benchmark::DoNotOptimize(localtime(&_now));}
}BENCHMARK_DEFINE_F(bm_mktime, localtime_TZ_shanghai)(benchmark::State &state)
{setenv("TZ", "Asia/Shanghai", 0);for (auto _ : state) {benchmark::DoNotOptimize(localtime(&_now));}
}

localtime_r接口测试,带时区与不带时区:

//
// localtime_r
//BENCHMARK_DEFINE_F(bm_mktime, localtime_r_TZ_NULL_isDST)(benchmark::State &state)
{unsetenv("TZ");_tm.tm_isdst = 1;for (auto _ : state) {benchmark::DoNotOptimize(localtime_r(&_now, &_tm));}
}BENCHMARK_DEFINE_F(bm_mktime, localtime_r_TZ_NULL_noDST)(benchmark::State &state)
{unsetenv("TZ");_tm.tm_isdst = 0;for (auto _ : state) {benchmark::DoNotOptimize(localtime_r(&_now, &_tm));}
}BENCHMARK_DEFINE_F(bm_mktime, localtime_r_TZ_empty_isDST)(benchmark::State &state)
{setenv("TZ", "", 0);_tm.tm_isdst = 1;for (auto _ : state) {benchmark::DoNotOptimize(localtime_r(&_now, &_tm));}
}BENCHMARK_DEFINE_F(bm_mktime, localtime_r_TZ_empty_noDST)(benchmark::State &state)
{setenv("TZ", "", 0);_tm.tm_isdst = 0;for (auto _ : state) {benchmark::DoNotOptimize(localtime_r(&_now, &_tm));}
}BENCHMARK_DEFINE_F(bm_mktime, localtime_r_TZ_shanghai_isDST)(benchmark::State &state)
{setenv("TZ", "Asia/Shanghai", 0);_tm.tm_isdst = 1;for (auto _ : state) {benchmark::DoNotOptimize(localtime_r(&_now, &_tm));}
}BENCHMARK_DEFINE_F(bm_mktime, localtime_r_TZ_shanghai_noDST)(benchmark::State &state)
{setenv("TZ", "Asia/Shanghai", 0);_tm.tm_isdst = 0;for (auto _ : state) {benchmark::DoNotOptimize(localtime_r(&_now, &_tm));}
}

mktime测试,带时区与不带时区

//
// mktime
//BENCHMARK_DEFINE_F(bm_mktime, mktime_TZ_NULL_isDST)(benchmark::State &state)
{unsetenv("TZ");_tm.tm_isdst = 1;for (auto _ : state) {benchmark::DoNotOptimize(mktime(&_tm));}
}BENCHMARK_DEFINE_F(bm_mktime, mktime_TZ_NULL_noDST)(benchmark::State &state)
{unsetenv("TZ");_tm.tm_isdst = 0;for (auto _ : state) {benchmark::DoNotOptimize(mktime(&_tm));}
}BENCHMARK_DEFINE_F(bm_mktime, mktime_TZ_empty_isDST)(benchmark::State &state)
{setenv("TZ", "", 0);_tm.tm_isdst = 1;for (auto _ : state) {benchmark::DoNotOptimize(mktime(&_tm));}
}BENCHMARK_DEFINE_F(bm_mktime, mktime_TZ_empty_noDST)(benchmark::State &state)
{setenv("TZ", "", 0);_tm.tm_isdst = 0;for (auto _ : state) {benchmark::DoNotOptimize(mktime(&_tm));}
}BENCHMARK_DEFINE_F(bm_mktime, mktime_TZ_shanghai_isDST)(benchmark::State &state)
{setenv("TZ", "Asia/Shanghai", 0);_tm.tm_isdst = 1;for (auto _ : state) {benchmark::DoNotOptimize(mktime(&_tm));}
}BENCHMARK_DEFINE_F(bm_mktime, mktime_TZ_shanghai_noDST)(benchmark::State &state)
{setenv("TZ", "Asia/Shanghai", 0);_tm.tm_isdst = 0;for (auto _ : state) {benchmark::DoNotOptimize(mktime(&_tm));}
}

4、测试结论

测试机器信息
内核:4.12.7
glibc:2.26
CPU:Intel® Xeon® CPU E5-2630 v4 @ 2.20GHz

编译方法,需要依赖libbenchmark

g++ -std=c++11 -Wall -O3 -Os -o bm_mktime bm_mktime.cc  \-lbenchmark -lbenchmark_main -pthread

测试结果如下:

2021-09-11 10:56:51
Running ./bm_mktime
Run on (16 X 2199.23 MHz CPU s)
CPU Caches:L1 Data 32K (x4)L1 Instruction 32K (x4)L2 Unified 256K (x4)L3 Unified 25600K (x4)
Load Average: 0.00, 0.00, 0.00
----------------------------------------------------------------------------------
Benchmark                                        Time             CPU   Iterations
----------------------------------------------------------------------------------
bm_mktime/localtime_TZ_null                    836 ns          836 ns       832463
bm_mktime/localtime_TZ_empty                   354 ns          354 ns      1968125
bm_mktime/localtime_TZ_shanghai                347 ns          347 ns      2006657
bm_mktime/localtime_r_TZ_NULL_isDST            299 ns          299 ns      2303871
bm_mktime/localtime_r_TZ_NULL_noDST            303 ns          303 ns      2307305
bm_mktime/localtime_r_TZ_empty_isDST           301 ns          301 ns      2315543
bm_mktime/localtime_r_TZ_empty_noDST           300 ns          300 ns      2322080
bm_mktime/localtime_r_TZ_shanghai_isDST        302 ns          302 ns      2208106
bm_mktime/localtime_r_TZ_shanghai_noDST        298 ns          298 ns      2335372
bm_mktime/mktime_TZ_NULL_isDST                 921 ns          921 ns       755271
bm_mktime/mktime_TZ_NULL_noDST                 923 ns          923 ns       758570
bm_mktime/mktime_TZ_empty_isDST                419 ns          419 ns      1651223
bm_mktime/mktime_TZ_empty_noDST                419 ns          419 ns      1687080
bm_mktime/mktime_TZ_shanghai_isDST             419 ns          419 ns      1664563
bm_mktime/mktime_TZ_shanghai_noDST             417 ns          417 ns      1691596

目前结果看,夏令时DST设置与否没有什么大的影响,但是TZ不设置会有相关的损耗;
(Q1:什么场景下会使用DST?)

Linux下mktime接口耗时测试相关推荐

  1. Redis第二集:Linux下安装Redis和测试,包含命令代码和问题处理办法,超详细版

    Redis第二集:Linux下安装Redis和测试,包含命令代码和问题处理办法,超详细版 一.资源 Linux下的Redis的下载地址 二.安装与测试 上传至自己的Linux平台 解压安装包 tar ...

  2. kali Linux下wifi密码安全测试(1)虚拟机下usb无线网卡的挂载 【转】

    转自:http://blog.chinaunix.net/uid-26349264-id-4455634.html 目录 kali Linux下wifi密码安全测试(1)虚拟机下usb无线网卡的挂载 ...

  3. linux udp 端口测试,RAKsmart:Linux下TCP/UDP 端口测试及验证方法说明

    RAKsmart:Linux下TCP/UDP 端口测试及验证方法说明2020-06-11 在 Linux 系统中,有时需要在系统中测试端口的连通性,以便确认系统的TCP.UDP协议栈是否可以正常运行. ...

  4. linux测试读写的工具,Linux 下的硬盘读写速度测试工具

    Linux 下的硬盘读写速度测试工具 执行一下以下命令看看你服务器的磁盘性能如何. hdparm -Tt /dev/sda 以下是 2块 希捷 ES2 SATA 500G 做 Raid0 的速度 [r ...

  5. Linux 下 N 卡 GPU 测试

    在win系统下测试工具比较多,现在 N 卡多用于深度学习,有时候会在 Linux下进行 N 卡测试. 测试工具 gpu-burn: Multi-GPU CUDA stress test,github地 ...

  6. linux 服务器 硬盘测试工具,Linux 下的硬盘读写速度测试工具

    Linux 下的硬盘读写速度测试工具 执行一下以下命令看看你服务器的磁盘性能如何. hdparm -Tt /dev/sda 以下是 2块 希捷 ES2 SATA 500G 做 Raid0 的速度 [r ...

  7. linux 开通udp 端口号,Linux 下 TCP/UDP 端口测试及验证方法说明

    Linux 下 TCP/UDP 端口测试及验证方法说明 在云服务器 ECS Linux 系统中,有时需要在系统中测试端口的连通性,以便确认系统的TCP.UDP协议栈是否可以正常运行.本文对此进行简要说 ...

  8. kali Linux下wifi密码安全测试(1)虚拟机下usb无线网卡的挂载_商洛学院司徒荆_新浪博客

    kali Linux下wifi密码安全测试(1)虚拟机下usb无线网卡的挂载 1.1     VMWare下的配置 1.2 VirtualBox下的配置 原文链接:http://www.xuanhun ...

  9. linux i2c调试命令,嵌入式Linux下I2C接口调试

    By Toradex秦海 1).简介 I2C是嵌入式设备最为常用的接口之一,常用于如下面这些应用场景,因此本文就基于嵌入式Linux演示在User Space进行I2C设备调试. - Digital ...

最新文章

  1. 2018.3.15校内互测总结-点分治-线段树
  2. 讨论工字型接收线圈天线不同匝数对于低频定位信号检测影响:150kHz导航信号
  3. ajax post对象参数,ajax用post方法传递参数
  4. 何时使用hadoop fs、hadoop dfs与hdfs dfs命令
  5. srm#397_div1_500pt 矩阵乘法+快速模幂
  6. ORA-12638: 身份证明检索失败
  7. 显著性目标检测matlab代码_显著性目标检测代码全汇总!(包含2D、3D、4D以及Video)...
  8. 关闭服务器系统关机事件,Windows Server 2012 系统提示意外关闭,事件ID:6008
  9. 定期存款转消费卡项目需求书
  10. 【No.4 变量作用域】
  11. 微信扫描二维码在内置浏览器打不开文件的下载链接怎么办?哪些api接口可以解决...
  12. 苹果被拒:Guideline 2.3.10 - Performance - Accurate Metadata
  13. 词法分析器java语言_Java语言词法分析器
  14. 如何将现有Apple ID 更改为美区
  15. 前端性能分析探索-天眼浏览器监控
  16. PostgreSQL文本搜索(七)——自定义配置
  17. 杜立特尔分解法 MATLAB,杜立特分解法.doc
  18. puppet kick 报错返回值code3 求解答(finished with exit code 3)
  19. 1's Complement和2's Complement的区别
  20. 【Python 邮件合并 pandas mailmerge】

热门文章

  1. Android百度地图实现定位
  2. prefab内容分析
  3. Understand 6.4.1141破解
  4. 大数据从业人员需要哪些技能?
  5. @Linux Centos系统优化与内核参数优化详解
  6. c语言编程实现飞机飞行速度,C语言实现简单飞机大战.pdf
  7. MySQL客户端命令Pager的使用操作
  8. BST的概念,以及查找,插入,删除算法
  9. 【高等数学】常用的等价无穷小替换
  10. Qt之QAbstractAnimation 实现网易云音乐背景墙图片轮换效果