Workaround for poor multithreaded localtime_s () performance on Windows

It seems that localtime_s() (which is equivalent to the localtime_r standard) contains a critical section in MSVC.

For comparison, here are two sample applications, one is localtime_s in a loop, the other is gmtime_s .

Profiling shows a hard blocking violation inside isindst caused from common_localtime_s<__int64> :

local lock conflict

gmtime does not detect a problem:

gmtime without blocking

Is there a way around this to get localtime_s working in a multi-threaded environment if I need local times in my process?

+6
source share
2 answers

Here is one suggested solution:

Record all the time at any of the fastest. When you present them to the user through a graphical interface, a log file or something else, do the conversion to local time.

Since most graphical interfaces and log output are single-threaded, this should remove competition from the rest of the program.

If the program never presents the data to the user, simply write it in quick time format and use the post-processing tool to convert or display it.

+2
source

Since the standard implementation uses locks and there is no easy way around it, you may have to use a different implementation. I would recommend trying to focus it on GetTimeZoneInformationForYear , which will provide you with an offset from UTC for standard and DST time and dates during which DST is valid. You also have the opportunity to call this time for each year that you care about and cache the result for use by all your threads.

Since gmtime_s works reasonably well, I would recommend that you use it to get the year. (Note that this is what localtime_s does). Subtract the corresponding offset value provided by GetTimeZoneInformationForYear , then use gmtime_s again to break it down into date components.

+2
source

All Articles