Linux下mktime接口耗时测试
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接口耗时测试相关推荐
- Redis第二集:Linux下安装Redis和测试,包含命令代码和问题处理办法,超详细版
Redis第二集:Linux下安装Redis和测试,包含命令代码和问题处理办法,超详细版 一.资源 Linux下的Redis的下载地址 二.安装与测试 上传至自己的Linux平台 解压安装包 tar ...
- kali Linux下wifi密码安全测试(1)虚拟机下usb无线网卡的挂载 【转】
转自:http://blog.chinaunix.net/uid-26349264-id-4455634.html 目录 kali Linux下wifi密码安全测试(1)虚拟机下usb无线网卡的挂载 ...
- linux udp 端口测试,RAKsmart:Linux下TCP/UDP 端口测试及验证方法说明
RAKsmart:Linux下TCP/UDP 端口测试及验证方法说明2020-06-11 在 Linux 系统中,有时需要在系统中测试端口的连通性,以便确认系统的TCP.UDP协议栈是否可以正常运行. ...
- linux测试读写的工具,Linux 下的硬盘读写速度测试工具
Linux 下的硬盘读写速度测试工具 执行一下以下命令看看你服务器的磁盘性能如何. hdparm -Tt /dev/sda 以下是 2块 希捷 ES2 SATA 500G 做 Raid0 的速度 [r ...
- Linux 下 N 卡 GPU 测试
在win系统下测试工具比较多,现在 N 卡多用于深度学习,有时候会在 Linux下进行 N 卡测试. 测试工具 gpu-burn: Multi-GPU CUDA stress test,github地 ...
- linux 服务器 硬盘测试工具,Linux 下的硬盘读写速度测试工具
Linux 下的硬盘读写速度测试工具 执行一下以下命令看看你服务器的磁盘性能如何. hdparm -Tt /dev/sda 以下是 2块 希捷 ES2 SATA 500G 做 Raid0 的速度 [r ...
- linux 开通udp 端口号,Linux 下 TCP/UDP 端口测试及验证方法说明
Linux 下 TCP/UDP 端口测试及验证方法说明 在云服务器 ECS Linux 系统中,有时需要在系统中测试端口的连通性,以便确认系统的TCP.UDP协议栈是否可以正常运行.本文对此进行简要说 ...
- kali Linux下wifi密码安全测试(1)虚拟机下usb无线网卡的挂载_商洛学院司徒荆_新浪博客
kali Linux下wifi密码安全测试(1)虚拟机下usb无线网卡的挂载 1.1 VMWare下的配置 1.2 VirtualBox下的配置 原文链接:http://www.xuanhun ...
- linux i2c调试命令,嵌入式Linux下I2C接口调试
By Toradex秦海 1).简介 I2C是嵌入式设备最为常用的接口之一,常用于如下面这些应用场景,因此本文就基于嵌入式Linux演示在User Space进行I2C设备调试. - Digital ...
最新文章
- 2018.3.15校内互测总结-点分治-线段树
- 讨论工字型接收线圈天线不同匝数对于低频定位信号检测影响:150kHz导航信号
- ajax post对象参数,ajax用post方法传递参数
- 何时使用hadoop fs、hadoop dfs与hdfs dfs命令
- srm#397_div1_500pt 矩阵乘法+快速模幂
- ORA-12638: 身份证明检索失败
- 显著性目标检测matlab代码_显著性目标检测代码全汇总!(包含2D、3D、4D以及Video)...
- 关闭服务器系统关机事件,Windows Server 2012 系统提示意外关闭,事件ID:6008
- 定期存款转消费卡项目需求书
- 【No.4 变量作用域】
- 微信扫描二维码在内置浏览器打不开文件的下载链接怎么办?哪些api接口可以解决...
- 苹果被拒:Guideline 2.3.10 - Performance - Accurate Metadata
- 词法分析器java语言_Java语言词法分析器
- 如何将现有Apple ID 更改为美区
- 前端性能分析探索-天眼浏览器监控
- PostgreSQL文本搜索(七)——自定义配置
- 杜立特尔分解法 MATLAB,杜立特分解法.doc
- puppet kick 报错返回值code3 求解答(finished with exit code 3)
- 1's Complement和2's Complement的区别
- 【Python 邮件合并 pandas mailmerge】