Live data from Hacker News

How setting the TZ environment variable avoids thousands of system calls

blog.packagecloud.io

21–30 of 148 posts

Re: How setting the TZ environment variable avoids thousands of system calls

#21

Is there a reason why the path to the timezone file is prefixed with a colon? TZ=:/etc/localtime I've set TZ sometimes without the colon and it seem to work. I did a quick online search and didn't find anything relevant.

Here is the answer:

https://www.gnu.org/software/libc/manual/html_node/TZ-Variab...

  The third format looks like this:

  :characters

  Each operating system interprets this format differently; in the GNU C
  Library, characters is the name of a file which describes the time zone.
The other formats specify the timezone directly, such as EST+5EDT. Interestingly, it seems to work okay without the colon. Perhaps the leading slash implies a filename?

Re: How setting the TZ environment variable avoids thousands of system calls

#22
post #19

Is there a reason why the path to the timezone file is prefixed with a colon? TZ=:/etc/localtime I've set TZ sometimes without the colon and it seem to work. I did a quick online search and didn't find anything relevant.

: means "read it from the " file. See the last part of the relevant glibc documentation: https://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_... However the reason it works without : is that the implementation is being lazy and just ignores the : delimiter and falls back to parsing out a filename either way: https://sourceware.org/git/?p=glibc.git;a=blob;f=time/tzset....

You beat me to it. I was answering my own question when one of my users came in with a problem. Stupid users...

Re: How setting the TZ environment variable avoids thousands of system calls

#23
post #18

System calls in Linux are really fast. So saving "thousands" of system calls when /etc/localtime is in cache doesn't actually save that much actual CPU time. I ran an experiment where I timed the runtime of the sample program provided in the OP, except I changed the number of calls to localtime() from ten times to a million. I then timed the difference with and without export TZ=:/etc/localhost. The net savings was .…

On your base system, yes. Lots of things can hook random syscalls, or environments might have syscall monitoring.

One example is the folks over at slack record every syscall for security auditing. https://slack.engineering/syscall-auditing-at-scale-e6a3ca8a...

Re: How setting the TZ environment variable avoids thousands of system calls

#25

If this has a real-world/measurable/etc. impact why isn't this set by default? Are there potential side-effects? Is it set in some distros but not others?

Portability, compatibility. The system should not set environment variables if there is a reasonable default action. Env is intended to be set by the user.

In general, the timezone is set during OS setup, and the system is left in a state where it's up to the applications to figure out what to do. For example, you might configure Apache (yes, I am old, leave me alone) to use a particular timezone. But if Apache senses an env var it may choose to override the configured value with what's in the env var. Or SSH might be configured to pass along all env vars, including TZ, which in all honesty it probably won't even if you tried, but it could, and then the destination server's application has the wrong timezone.

Point is, it's safer not to mess with env vars unless you need to.

Re: How setting the TZ environment variable avoids thousands of system calls

#26
post #18

System calls in Linux are really fast. So saving "thousands" of system calls when /etc/localtime is in cache doesn't actually save that much actual CPU time. I ran an experiment where I timed the runtime of the sample program provided in the OP, except I changed the number of calls to localtime() from ten times to a million. I then timed the difference with and without export TZ=:/etc/localhost. The net savings was .…

Yeah, this is a perfect example of micro-optimization being unnecessary. Not only will you not see performance issues from this in the real world, it might cause problems down the road, because since it isn't set by default this way, some apps may not expect it and behave erroneously.

But it's neat information to have in the back of your head.

Re: How setting the TZ environment variable avoids thousands of system calls

#28

It is perhaps out of scope of the article, but it sure would have been helpful to show how to set the TZ environment variable and what to set it to.

Its right there in middle of article (under "Preventing extraneous system calls" section):

    $ TZ=:/etc/localtime strace -ttT ./test

Re: How setting the TZ environment variable avoids thousands of system calls

#29
post #18

System calls in Linux are really fast. So saving "thousands" of system calls when /etc/localtime is in cache doesn't actually save that much actual CPU time. I ran an experiment where I timed the runtime of the sample program provided in the OP, except I changed the number of calls to localtime() from ten times to a million. I then timed the difference with and without export TZ=:/etc/localhost. The net savings was .…

This might be true for your system and libc, where the system calls make use of things like vDSO for gettimeofday go fast, but in general this isn't guaranteed at all. Even on x64, for certain libc implementations, like musl, if I recall correctly, syscalls are made the old fashioned way by trapping 0x80, which would mean you would see a much bigger effect by reducing the number of syscalls.

Re: How setting the TZ environment variable avoids thousands of system calls

#30
post #18

System calls in Linux are really fast. So saving "thousands" of system calls when /etc/localtime is in cache doesn't actually save that much actual CPU time. I ran an experiment where I timed the runtime of the sample program provided in the OP, except I changed the number of calls to localtime() from ten times to a million. I then timed the difference with and without export TZ=:/etc/localhost. The net savings was .…

Yeah, this is a perfect example of micro-optimization being unnecessary. Not only will you not see performance issues from this in the real world, it might cause problems down the road, because since it isn't set by default this way, some apps may not expect it and behave erroneously. But it's neat information to have in the back of your head.

Unnecessary? I had a really bad experience with ancient skype version on modern Ubuntu desktop, and the fix for this was to set TZ environment variable to speedup first login/history fetch. Skype process was spending so much time doing useless work it was noticeable.
Post reply on HN