mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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
This commit is contained in:
parent
43811cc3b3
commit
4d7a6d04b2
2 changed files with 14 additions and 11 deletions
14
hash.c
14
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;
|
||||
|
|
11
time.c
11
time.c
|
@ -3139,15 +3139,10 @@ find_time_t(struct tm *tptr, int utc_p, time_t *tp)
|
|||
|
||||
find_dst = 0 < tptr->tm_isdst;
|
||||
|
||||
#if defined(HAVE_MKTIME)
|
||||
tm0 = *tptr;
|
||||
if (!utc_p && (guess = mktime(&tm0)) != -1) {
|
||||
tm = GUESS(&guess);
|
||||
if (tm && tmcmp(tptr, tm) == 0) {
|
||||
goto found;
|
||||
}
|
||||
/* /etc/localtime might be changed. reload it. */
|
||||
if (!ruby_tz_uptodate_p) {
|
||||
tzset();
|
||||
}
|
||||
#endif
|
||||
|
||||
tm0 = *tptr;
|
||||
if (tm0.tm_mon < 0) {
|
||||
|
|
Loading…
Reference in a new issue