I have run into an interesting performance conundrum but before I start delving into glibc and entering bugs left right and center I just wanted to get to get any insight that might be out there.
I have code that in one of the functions does this:
gettimeofday( &tv, 0);
localtime_r( &tv.tv_sec, &local_tm );
char result[25];
strftime( result, 24, "%Y-%m-%d %H:%M:%S", &local_tm);
The rest of the code is irrelevant for this question. When I replace it with this:
gettimeofday( &tv, 0);
localtime_r( &tv.tv_sec, &local_tm );
char result[25];
snprintf(result, sizeof(result), "%04d-%02d-%02d %02d:%02d:%02d",
local_tm.tm_year+1900, local_tm.tm_mon+1,
local_tm.tm_mday, local_tm.tm_hour, local_tm.tm_min,
local_tm.tm_sec);
on average I get 20% performance boost.
Has anyone ran into this? Is this OS specific?
Using sprintf and snprintf for concatenation This results in code that is eminently readable but, owing to snprintf's considerable overhead, can be orders of magnitude slower than using the string functions even with their inefficiencies.
It is more than 6 times slower than fmt::format_int . One possible reason for this is that sprintf parses the format string, but so do fmt::format and fmt::format_to which are 1.8 - 2.6 times faster than sprintf . The good thing is that you don't have to use sprintf in an attempt to sacrifice safety for performance.
POSIX requires strftime
to call tzset()
(or act as if it did), which on a linux system will likely stat /etc/timezone and other files, which is slow (compared to snprintf). Setting the TZ
environment variable will generally give it a great boost.
As was said in the comments it also localizes the message.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With