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…
	
	Add table
		Add a link
		
	
		Reference in a new issue