TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

How setting the TZ environment variable avoids thousands of system calls

472 点作者 jcapote大约 8 年前

34 条评论

AceJohnny2大约 8 年前
&gt; <i>In other words: your system supports calling the time system call via the Linux kernel’s vDSO to avoid the cost of switching to the kernel. But, as soon as your program calls time, it calls localtime immediately after, which invokes a system call anyway.</i><p>This reminds me of an article by Ted Unangst[1], in which he flattens the various libraries and abstractions to show how xterm (to cite one of many culprits) in one place is effectively doing:<p><pre><code> if (poll() || poll()) while (poll()) { &#x2F;* ... *&#x2F; } </code></pre> In other words, if you don&#x27;t know what your library&#x2F;abstraction is doing, you can end up accidentally duplicating its work.<p>Reminds me of some aphorism, &quot;Those who do not learn from history...&quot; ;)<p>[1] <a href="http:&#x2F;&#x2F;www.tedunangst.com&#x2F;flak&#x2F;post&#x2F;accidentally-nonblocking" rel="nofollow">http:&#x2F;&#x2F;www.tedunangst.com&#x2F;flak&#x2F;post&#x2F;accidentally-nonblocking</a><p>discussed <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=11847529" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=11847529</a>
评论 #13699860 未加载
评论 #13700298 未加载
评论 #13703498 未加载
tytso大约 8 年前
System calls in Linux are really fast. So saving &quot;thousands&quot; of system calls when &#x2F;etc&#x2F;localtime is in cache doesn&#x27;t actually save that much actual CPU time.<p>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=:&#x2F;etc&#x2F;localhost. The net savings was .6 seconds. So for a single call to localtime(3), the net savings is 0.6 microseconds.<p>That&#x27;s non-zero, but it&#x27;s likely in the noise compared to everything else that your program might be doing.
评论 #13699973 未加载
评论 #13698778 未加载
评论 #13699014 未加载
评论 #13699916 未加载
评论 #13704865 未加载
评论 #13703976 未加载
评论 #13698924 未加载
评论 #13704585 未加载
评论 #13700622 未加载
pquerna大约 8 年前
Good blog post explaining the behavior of glibc, I also saw this first hand when profiling Apache awhile back too:<p><a href="http:&#x2F;&#x2F;mail-archives.apache.org&#x2F;mod_mbox&#x2F;httpd-dev&#x2F;201111.mbox&#x2F;%3CCAMDeyhzRAZ4eyz%3D%2BstA%3DwoTibM-W6QL8TqT%2BaPio07UddCz7Tg%40mail.gmail.com%3E" rel="nofollow">http:&#x2F;&#x2F;mail-archives.apache.org&#x2F;mod_mbox&#x2F;httpd-dev&#x2F;201111.mb...</a><p><a href="https:&#x2F;&#x2F;github.com&#x2F;apache&#x2F;httpd&#x2F;blob&#x2F;trunk&#x2F;server&#x2F;util_time.c#L310-L327" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;apache&#x2F;httpd&#x2F;blob&#x2F;trunk&#x2F;server&#x2F;util_time....</a><p>The internals of glibc can often be pretty surprising sometimes, I&#x27;d really encourage people to go spelunking into the glibc source when they are profiling applications.
brendangregg大约 8 年前
Please quantify the speedup (I&#x27;ve found this before, but it&#x27;s never been a significant issue). Eliminating unnecessary work is great, but what are we really talking about here? Use a CPU flamegraph, Ctrl-F and search for stat functions. It&#x27;ll quantify the total on the bottom right.
评论 #13702624 未加载
Daviey大约 8 年前
Honestly, the primary reason I support this is to get developers out of the habbit of demanding a localized server timezone. As an infra&#x27; person, I want system time in UTC. If developers get in the habbit of setting TZ, then I can have this!
评论 #13710702 未加载
jdamato大约 8 年前
Author of the post here: greetings.<p>If you enjoyed this post, you may also enjoy our deep dive explaining exactly how system calls work on Linux[1].<p>[1]: <a href="https:&#x2F;&#x2F;blog.packagecloud.io&#x2F;eng&#x2F;2016&#x2F;04&#x2F;05&#x2F;the-definitive-guide-to-linux-system-calls&#x2F;" rel="nofollow">https:&#x2F;&#x2F;blog.packagecloud.io&#x2F;eng&#x2F;2016&#x2F;04&#x2F;05&#x2F;the-definitive-g...</a>
rootbear大约 8 年前
Is there a reason why the path to the timezone file is prefixed with a colon?<p>TZ=:&#x2F;etc&#x2F;localtime<p>I&#x27;ve set TZ sometimes without the colon and it seem to work. I did a quick online search and didn&#x27;t find anything relevant.
评论 #13698447 未加载
评论 #13698562 未加载
评论 #13704239 未加载
评论 #13698443 未加载
snowcrshd大约 8 年前
Brendan Gregg wrote about this a few years ago [1].<p>My favorite part:<p>&gt; WTF?? Why is ls(1) running stat() on &#x2F;etc&#x2F;localtime for every line of output?<p>[1] <a href="http:&#x2F;&#x2F;www.brendangregg.com&#x2F;blog&#x2F;2014-05-11&#x2F;strace-wow-much-syscall.html" rel="nofollow">http:&#x2F;&#x2F;www.brendangregg.com&#x2F;blog&#x2F;2014-05-11&#x2F;strace-wow-much-...</a>
glandium大约 8 年前
What is missing in this post is:<p>- Why does glibc check &#x2F;etc&#x2F;localtime every time localtime is called? Wild guess: so that new values of &#x2F;etc&#x2F;localtime are picked at runtime without restarting programs.<p>- Corollary: why does glibc <i>not</i> check &#x2F;etc&#x2F;localtime every time localtime is called, when TZ is set to :&#x2F;etc&#x2F;localtime? Arguably the reason above should still apply when TZ is set to a file name, shouldn&#x27;t it?
评论 #13703369 未加载
评论 #13709034 未加载
评论 #13701479 未加载
jonathonf大约 8 年前
If this has a real-world&#x2F;measurable&#x2F;etc. impact why isn&#x27;t this set by default? Are there potential side-effects? Is it set in some distros but not others?
评论 #13698804 未加载
评论 #13700253 未加载
评论 #13698163 未加载
leovonl大约 8 年前
This seems to be a simple RTFM issue to me: POSIX specifies that gmtime() uses UTC and localtime() uses current timezone. Using gmtime() would implement the desired behaviour without any need to hardcode environment variables.
评论 #13699985 未加载
rdtsc大约 8 年前
Great post. I remember when vDSOs were added we noticed a nice speedup in our code. We tuned for realtime and a few microseconds here and there add up. Most importantly, less systems calls means more predictability.
blunte大约 8 年前
This reminds me of a very similar behavior in Solaris over 20 years ago. Our C application was having odd performance problems on some client systems, and eventually we saw via truss that there were hundreds of fopen() calls every second to get the timezone. Setting the right environment variable solved the problem.
kelnos大约 8 年前
I really enjoy when people dig into things like this and report their findings. Having said that, I question the wisdom of &quot;bothering&quot; with this sort of thing. Everything you do that&#x27;s non-standard or works against a system&#x27;s default behavior incurs a cost. It&#x27;s yet another thing you have to replicate when you migrate to a new version, change provisioning systems, etc.<p>And for what benefit? A few hundred syscalls per second? Linux syscalls are fast enough that something of that magnitude shouldn&#x27;t matter much. Given that &#x2F;etc&#x2F;localtime will certainly be in cache with that frequency of access, a stat() should do little work in the kernel to return, so that won&#x27;t be slow either.<p>It&#x27;s good that they did some benchmarking to look at the differences, but this feels like a premature optimization to me. I can&#x27;t imagine that this did anything but make their application a tiny fraction of a percent faster. Was it worth the time to dig into that for this increase? Was it worth the maintenance cost I mention in my first paragraph? I wouldn&#x27;t think so.<p>I&#x27;m really trying not to take a crap on what they did; as I said, it&#x27;s really cool to dig into these sorts of abstractions and find out where they&#x27;re inefficient or leak (or just great as a learning exercise; we all depend on a mountain of code that most people don&#x27;t understand at all). But, when looked at from a holistic systems approach, a grab bag of little &quot;tweaks&quot; like this can become harmful in the long run.
评论 #13700715 未加载
评论 #13705478 未加载
scottlamb大约 8 年前
There&#x27;s another easy way to avoid this: use localtime_r instead of localtime. From the glibc source:<p><pre><code> &#x2F;* Update internal database according to current TZ setting. POSIX.1 8.3.7.2 says that localtime_r is not required to set tzname. This is a good idea since this allows at least a bit more parallelism. *&#x2F; tzset_internal (tp == &amp;_tmbuf &amp;&amp; use_localtime, 1); </code></pre> mktime also does the tzset call every time, though:<p><pre><code> time_t mktime (struct tm *tp) { #ifdef _LIBC &#x2F;* POSIX.1 8.1.1 requires that whenever mktime() is called, the time zone names contained in the external variable &#x27;tzname&#x27; shall be set as if the tzset() function had been called. *&#x2F; __tzset (); #endif </code></pre> and I don&#x27;t see any way around that other than setting TZ=: or some such.
rocky1138大约 8 年前
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.
评论 #13698969 未加载
falsedan大约 8 年前
Why did this post start with a tl;dr, then a Summary, and _still_ buried the important takeaway in the ultimate paragraph?
rtsisyk大约 8 年前
BTW, packagecloud.io is the great hosting for RPM&#x2F;DEB packages. We&#x27;ve been using it for the last couple years. GitHub + Travis CI + PackageCloud combination allows us build and publish packages for EVERY git commit in 30+ repositories targeting 15 different Linux distributions [1]. There is no more need to hire a special devops guy for that.<p>[1]: <a href="https:&#x2F;&#x2F;github.com&#x2F;packpack&#x2F;packpack#packpack" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;packpack&#x2F;packpack#packpack</a>
hodgesrm大约 8 年前
Interesting article but I can&#x27;t reproduce the behavior on Ubuntu 16.01 LTS. I don&#x27;t have TZ set (or anything locale-related for that matter). Here are the library dependencies:<p><pre><code> $ ldd test linux-vdso.so.1 =&gt; (0x00007ffd80baf000) libc.so.6 =&gt; &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc.so.6 (0x00007f8844bf7000) &#x2F;lib64&#x2F;ld-linux-x86-64.so.2 (0x00007f8844fbc000) </code></pre> Any thoughts why the behavior would be different?
评论 #13703547 未加载
acscott大约 8 年前
This reminds me of setting noatime for disk mounts (<a href="http:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;2099&#x2F;is-it-worth-to-tune-ext4-with-noatime" rel="nofollow">http:&#x2F;&#x2F;askubuntu.com&#x2F;questions&#x2F;2099&#x2F;is-it-worth-to-tune-ext4...</a>)<p>Now I want to know the number of other configs to reduce the number of system calls. This all adds up to being significant the greater the number of hosts in your environment.
actuator大约 8 年前
While trying to find the cause of slowness in Rails requests, I was running strace on an unicorn process when I encountered the same thing mentioned in the article.<p>Rails instrumentation code calls current time before and after any instrumentation block. So, when I looked at the trace there were a lot of `stat` calls coming for `&#x2F;etc&#x2F;localtime` and as stat is an IO operation, I thought I discovered the cause of slowness(which I attributed to high number of IO ops) but surprisingly when I saw the strace method summary; while the call count was high, the time taken by the calls in total was not significant(&lt;1% if I remember correctly). So I decided to set TZ with the next AMI update 15 months back but forgot about it totally. I guess I should add it to my Trello list this time.<p>Also, I think he should have printed the aggregate summary of just CPU clock time(`-c`) as well as that is usually very low.
评论 #13701728 未加载
astrostl大约 8 年前
I do this for &quot;not get annoyed while stracing&quot; reasons, not perf!
rargulati大约 8 年前
Really interesting - thanks for sharing the findings. I haven&#x27;t seen it mentioned here, but for those of us using `timedatectl` via systemd, with the default setting of `UTC` are taking advantage[1] of the recommendation in the article.<p>[1] <a href="https:&#x2F;&#x2F;github.com&#x2F;systemd&#x2F;systemd&#x2F;blob&#x2F;master&#x2F;src&#x2F;timedate&#x2F;timedatectl.c#L85" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;systemd&#x2F;systemd&#x2F;blob&#x2F;master&#x2F;src&#x2F;timedate&#x2F;...</a>
cbsmith大约 8 年前
This reads to me like a glibc bug. Glibc should just be watching &quot;&#x2F;etc&#x2F;localtime&quot; for changes, rather than calling out to hundreds of times a second.
评论 #13700214 未加载
评论 #13700166 未加载
评论 #13700135 未加载
drudru11大约 8 年前
Side note - why do some sites completely hide information about who is behind them? I couldn&#x27;t find a single thing about that on their blog or main site.
评论 #13698508 未加载
评论 #13698125 未加载
评论 #13698128 未加载
kseistrup大约 8 年前
It would be highly inconvenient to have to set this variable if you live in a country where you change the timezone twice a year due to summertime.
评论 #13699298 未加载
评论 #13699249 未加载
评论 #13699842 未加载
评论 #13704084 未加载
评论 #13699517 未加载
barrystaes大约 8 年前
Im not an expert but the first thing that comes to mind is that 1) TFA does not quantify the performance gain in time 2) I wonder if environment variables like TZ are a security risk&#x2F;vector in that these might facilitate attackers to stealthy skew&#x2F;screw time within current user process... no root required.
jakeogh大约 8 年前
OpenRC users can:<p><pre><code> echo &#x27;TZ=:&#x2F;etc&#x2F;localtime&#x27; &gt; &#x2F;etc&#x2F;env.d&#x2F;00localtime</code></pre>
评论 #13711076 未加载
rtsisyk大约 8 年前
Overhead of localtime() is well-known, just RTFM. Anyway, this article provides very good explanation.
creeble大约 8 年前
Does anyone have any evidence of this actually having a resource usage impact on any common programs?<p>I see one reference to Apache below, but not whether it actually made a measurable difference.
vesinisa大约 8 年前
This was a thoroughly fascinating read. Highly recommend reading the previous part in the series as well.
mozumder大约 8 年前
Does this affect FreeBSD as well?
评论 #13699107 未加载
评论 #13699482 未加载
dpatru大约 8 年前
It seems to me that this is something the Linux distributions should already be doing.
sandGorgon大约 8 年前
does anyone know if this impacts docker images as well ?
评论 #13698010 未加载
评论 #13697985 未加载
评论 #13697978 未加载