localtime 的性能問題及其替代者


在系統從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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM