Bug 171351

Summary: strftime is unreasonably slow because of tzset
Product: [Fedora] Fedora Reporter: Tom Lane <tgl>
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact: Brian Brock <bbrock>
Severity: low Docs Contact:
Priority: medium    
Version: 4CC: drepper, fweimer, hhorak
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-10-21 07:50:48 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Tom Lane 2005-10-20 22:38:18 UTC
Description of problem:
While analyzing a performance problem in PostgreSQL, I found out that each call
to strftime() resulted in a stat64("/etc/localtime") kernel call.  The source
code says that POSIX.1 requires that strftime act as if it called tzset, which
is fine, but surely POSIX.1 doesn't require stat'ing an external file.  Couldn't
this be fixed so that it behaves more like localtime(), ie, we only have to pay
a strcmp() to decide that the info is up to date?  Specifically I think strftime
ought to result in the equivalent of tzset_internal(1, 0) not
tzset_internal(1, 1).

Version-Release number of selected component (if applicable):
glibc-2.3.5-10.3

How reproducible:
100%

Steps to Reproduce:
1. Write tight loop involving strftime() call.
2. strace the test program, having made sure TZ envar is not set.
  
Actual results:
Large number of stat64 syscalls.

Expected results:
Once into the loop, no syscalls should be needed.

Additional info:
It looks like mktime() has the same issue, though I didn't test it explicitly.

Comment 1 Jakub Jelinek 2005-10-21 07:50:48 UTC
If strftime called tzset_internal(1, 0), it would violate POSIX, as it would no
longer act as if it called tzset.
The reason for the stat is to allow for timezone changes.
If you don't want that, you can just use TZ=/etc/localtime or TZ=Europe/Prague
or whatever timezone you want to use.