summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authorKOSAKI Motohiro <kosaki.motohiro@gmail.com>2019-12-01 16:21:05 +0000
committerKOSAKI Motohiro <kosaki.motohiro@gmail.com>2019-12-01 16:34:26 +0000
commit4d7a6d04b2c71aabb9d6e619f4405887806a5be8 (patch)
treec27f7dff69239308bca5e36ea4593d67a074ace8 /hash.c
parent43811cc3b36739816788cbbac7a49b9bbf756293 (diff)
Avoid unnecessary tzset() call
Akatsuki reported ENV['TZ'] = 'UTC' improved 7x-8x faster on following code. t = Time.now; 100000.times { Time.new(2019) }; Time.now - t https://hackerslab.aktsk.jp/2019/12/01/141551 commit 4bc1669127(reduce tzset) dramatically improved this situation. But still, TZ=UTC is faster than default. This patch removs unnecessary tzset() call completely. Performance check ---------------------- test program: t = Time.now; 100000.times { Time.new(2019) }; Time.now - t before: 0.387sec before(w/ TZ): 0.197sec after: 0.162sec after(w/ TZ): 0.165sec OK. Now, Time creation 2x faster *and* TZ=UTC doesn't improve anything. We can forget this hack completely. :) Side note: This patch slightly changes Time.new(t) behavior implicitly. Before this patch, it might changes default timezone implicitly. But after this patch, it doesn't. You need to reset TZ (I mean ENV['TZ'] = nil) explicitly. But I don't think this is big impact. Don't try to change /etc/localtime on runtime. Side note2: following test might be useful for testing "ENV['TZ'] = nil". ----------------------------------------- % cat <<'End' | sudo sh -s rm -f /etc/localtime-; cp -a /etc/localtime /etc/localtime- rm /etc/localtime; ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime ./ruby -e ' p Time.new(2000).zone # JST File.unlink("/etc/localtime"); File.symlink("/usr/share/zoneinfo/America/Los_Angeles", "/etc/localtime") p Time.new(2000).zone # JST (ruby does not follow /etc/localtime modification automatically) ENV["TZ"] = nil p Time.new(2000).zone # PST (ruby detect /etc/localtime modification) ' rm /etc/localtime; cp -a /etc/localtime- /etc/localtime; rm /etc/localtime- End
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/hash.c b/hash.c
index 6b3f844095..0b3745cf6e 100644
--- a/hash.c
+++ b/hash.c
@@ -4711,6 +4711,17 @@ env_delete(VALUE name)
nam = env_name(name);
val = getenv(nam);
+
+ /*
+ * ENV['TZ'] = nil has a special meaning.
+ * TZ is no longer considered up-to-date and ruby call tzset() as needed.
+ * It could be useful if sysadmin change /etc/localtime.
+ * This hack might works only on Linux glibc.
+ */
+ if (ENVMATCH(nam, TZ_ENV)) {
+ ruby_tz_uptodate_p = FALSE;
+ }
+
if (val) {
VALUE value = env_str_new2(val);
@@ -4718,9 +4729,6 @@ env_delete(VALUE name)
if (ENVMATCH(nam, PATH_ENV)) {
RB_GC_GUARD(name);
}
- else if (ENVMATCH(nam, TZ_ENV)) {
- ruby_tz_uptodate_p = false;
- }
return value;
}
return Qnil;