localtime 的性能问题及其替代者

本文探讨了从RedHat5升级至RedHat6后,因频繁调用localtime_r导致的服务性能下降问题,并提出了一种名为FastSecondToDate的替代方案,通过数学计算而非系统调用来获取日期时间信息,显著提升了性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在系统从redhat5升到redhat6的过程中,服务的性能差了很多。经过定位发现是程序中频繁调用localtime/localtime_r所致。

而调用localtime_r 的实现中,对时区进行了加锁,有bug反馈其有切换的性能损耗。

修复服务程序就有两种思路。

1. 减少localtime_r的调用。

2. 寻找localtime_r的替换者。

第一种思路比较简单,用一个变量调用一次,需要的时候就用该变量即可。

下面谈一下第二种思路。我们的系统调用localtime_r主要是为了获取tm结构中的有限几个域,如时分秒等。我们找到了

进行日期时间转换和计算的几个Shell小函数》这样通过计算得到tm结构的方法,将其翻译为C++的程序FastSecondToDate,

对于其解释有一篇博文《一个精巧的日期差算法赏析》共参考。

在系统测试中,FastSecondToDate 基本上不耗时,性能有x200以上的提升。

附 FastSecondToDate的实现

static int FastSecondToDate(const time_t& unix_sec, struct tm* tm, int time_zone)
{
    static const int kHoursInDay = 24;
    static const int kMinutesInHour = 60;
    static const int kDaysFromUnixTime = 2472632;
    static const int kDaysFromYear = 153;
    static const int kMagicUnkonwnFirst = 146097;
    static const int kMagicUnkonwnSec = 1461;
    tm->tm_sec  =  unix_sec % kMinutesInHour;
    int i      = (unix_sec/kMinutesInHour);
    tm->tm_min  = i % kMinutesInHour; //nn
    i /= kMinutesInHour;
    tm->tm_hour = (i + time_zone) % kHoursInDay; // hh
    tm->tm_mday = (i + time_zone) / kHoursInDay;
    int a = tm->tm_mday + kDaysFromUnixTime;
    int b = (a*4  + 3)/kMagicUnkonwnFirst;
    int c = (-b*kMagicUnkonwnFirst)/4 + a;
    int d =((c*4 + 3) / kMagicUnkonwnSec);
    int e = -d * kMagicUnkonwnSec;
    e = e/4 + c;
    int m = (5*e + 2)/kDaysFromYear;
    tm->tm_mday = -(kDaysFromYear * m + 2)/5 + e + 1;
    tm->tm_mon = (-m/10)*12 + m + 2;
    tm->tm_year = b*100 + d  - 6700 + (m/10);
    return 0;
}

 

转载于:https://www.cnblogs.com/westfly/p/5139645.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值