Reference URL: https://gmbabar.wordpress.com/2010/12/01/mktime-slow-use-custom-function/
Recently I was doing work with timestamps in ASCII (c string) format. For different calculations, I often need to convert the timestamp string to epoch time. The standard C library provides the Mktime function, which passes the already populated TM structure as an argument to the Mktime function. If you don't use the function very often, it works very well. But if you need to convert tens of thousands of timestamp strings at run time, this function becomes the bottleneck for your application. I didn't try to read Mktime's source code and assembly codes, so I'm not sure why this function costs so much. But I just implemented my own custom function to complete the conversion of mktime. I can't believe the result. Each function runs a 1M call with the following results:
mktime:2950000 microseconds
time_to_epoch:60000 microseconds
Here is the source code for the custom function:
Note: When the zone is Beijing time, Utcdiff is set to 8 to get the UTC time, which is time (NULL).
time_t Time_to_epoch (const struct TM*LTM, int utcdiff) {
const int Mon_days [] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
Long Tyears, tdays, leaps,utc_hrs;
int i;
Tyears = ltm->tm_year–70; Tm->tm_year is from 1900.
Leaps = (Tyears + 2)/4;//No of next lines until year 2100.
i = (ltm->tm_year–100)/100;
Leaps-= ((I/4) + i%4);
tdays = 0;
for (i=0; I <ltm->tm_mon; i++) tdays + = Mon_days[i];
Tdays + = ltm->tm_mday-1;//days of month passed.
Tdays = Tdays + (tyears *365) + leaps;
utc_hrs = Ltm->tm_hour +utcdiff; For your time zone.
Return (Tdays * 86400) + (utc_hrs * 3600) + (Ltm->tm_min *) + ltm->tm_sec;
}
void Str_to_tm (char *mdate, char *mtime, structtm* MTM) {
CHAR*PSTR;
Long Year,month, day, Hour, Min, sec;
Year =strtol (Mdate, &PSTR, 10);
Month =strtol (++pstr, &PSTR, 10);
Day =strtol (++pstr, &PSTR, 10);
Hour =strtol (Mtime, &PSTR, 10); while (!isdigit (*PSTR)) ++pstr;
Min =strtol (pstr, &PSTR, 10); while (!isdigit (*PSTR)) ++pstr;
SEC =strtol (Pstr, &PSTR, 10);
Mtm->tm_sec = sec;
mtm->tm_min = min;
Mtm->tm_hour = hour;
Mtm->tm_mday = day;
Mtm->tm_mon = month–1;
Mtm->tm_year = year–1900;
}
int main (int argc, char *argv[]) {
Charmydate[] = "2010-11-30";
Charmytime[] = "11:30:45";
struct TMMTM;
Time_tticks, Mytcks;
Str_to_tm (MyDate, MyTime, &MTM);
Mytcks =time_to_epoch (&MTM, 5);
Ticks = Mktime (&MTM);
printf ("Std func time:%s", Asctime (LocalTime (&ticks)));
printf ("Our Func Time:%s", Asctime (LocalTime (&mytcks)));
printf ("Stdlib func ticks:%ld \ n", ticks);
printf ("Our func ticks:%ld \ n", mytcks);
}
The output is as follows:
STD func time:tue Nov 30 11:30:45 2010
Our func time:tue Nov 30 11:30:45 2010
STD func ticks:1291134645
Our func ticks:1291134645
What if Mktime is slow? Then use a custom Function!