Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: src/date-delay.js

Issue 126188: Improve DST offset computation performance. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/macros.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 return FromJulianDay(Day(time) + kDayZeroInJulianDay).date; 108 return FromJulianDay(Day(time) + kDayZeroInJulianDay).date;
109 } 109 }
110 110
111 111
112 // ECMA 262 - 15.9.1.9 112 // ECMA 262 - 15.9.1.9
113 function EquivalentYear(year) { 113 function EquivalentYear(year) {
114 // Returns an equivalent year in the range [2008-2035] matching 114 // Returns an equivalent year in the range [2008-2035] matching
115 // - leap year. 115 // - leap year.
116 // - week day of first day. 116 // - week day of first day.
117 var time = TimeFromYear(year); 117 var time = TimeFromYear(year);
118 var recent_year = (InLeapYear(time) == 0 ? 1967 : 1956) + 118 var recent_year = (InLeapYear(time) == 0 ? 1967 : 1956) +
119 (WeekDay(time) * 12) % 28; 119 (WeekDay(time) * 12) % 28;
120 // Find the year in the range 2008..2037 that is equivalent mod 28. 120 // Find the year in the range 2008..2037 that is equivalent mod 28.
121 // Add 3*28 to give a positive argument to the modulus operator. 121 // Add 3*28 to give a positive argument to the modulus operator.
122 return 2008 + (recent_year + 3*28 - 2008) % 28; 122 return 2008 + (recent_year + 3*28 - 2008) % 28;
123 } 123 }
124 124
125 125
126 function EquivalentTime(t) { 126 function EquivalentTime(t) {
127 // The issue here is that some library calls don't work right for dates 127 // The issue here is that some library calls don't work right for dates
128 // that cannot be represented using a non-negative signed 32 bit integer 128 // that cannot be represented using a non-negative signed 32 bit integer
129 // (measured in whole seconds based on the 1970 epoch). 129 // (measured in whole seconds based on the 1970 epoch).
130 // We solve this by mapping the time to a year with same leap-year-ness 130 // We solve this by mapping the time to a year with same leap-year-ness
131 // and same starting day for the year. The ECMAscript specification says 131 // and same starting day for the year. The ECMAscript specification says
132 // we must do this, but for compatability with other browsers, we use 132 // we must do this, but for compatibility with other browsers, we use
133 // the actual year if it is in the range 1970..2037 133 // the actual year if it is in the range 1970..2037
134 if (t >= 0 && t <= 2.1e12) return t; 134 if (t >= 0 && t <= 2.1e12) return t;
135 var day = MakeDay(EquivalentYear(YearFromTime(t)), MonthFromTime(t), DateFromT ime(t)); 135 var day = MakeDay(EquivalentYear(YearFromTime(t)), MonthFromTime(t), DateFromT ime(t));
136 return TimeClip(MakeDate(day, TimeWithinDay(t))); 136 return TimeClip(MakeDate(day, TimeWithinDay(t)));
137 } 137 }
138 138
139 var daylight_cache_time = $NaN; 139
140 var daylight_cache_offset; 140 // Because computing the DST offset is a pretty expensive operation
141 // we keep a cache of last computed offset along with a time interval
142 // where we know the cache is valid.
143 var DST_offset_cache = {
144 // Cached DST offset.
145 offset: 0,
146 // Time interval where the cached offset is valid.
147 start: 0, end: -1,
148 // Size of next interval expansion.
149 increment: 0
150 };
151
141 152
142 function DaylightSavingsOffset(t) { 153 function DaylightSavingsOffset(t) {
William Hesse 2009/06/16 07:11:29 Comment the function to state that the algorithm i
143 if (t == daylight_cache_time) { 154 // Load the cache object from the builtins object.
144 return daylight_cache_offset; 155 var cache = DST_offset_cache;
156
157 // Cache the start and the end in local variables for fast access.
158 var start = cache.start;
159 var end = cache.end;
160
161 if (start <= t) {
162 // If the time fits in the cached interval, return the cached offset.
163 if (t <= end) return cache.offset;
164
165 // Compute a possible new interval end.
166 var new_end = end + cache.increment;
167
168 if (t <= new_end) {
169 var end_offset = %DateDaylightSavingsOffset(EquivalentTime(new_end));
170 if (cache.offset == end_offset) {
171 // If the offset at the end of the new interval still matches
172 // the offset in the cache, we grow the cached time interval
173 // and return the offset.
174 cache.end = new_end;
175 cache.increment = msPerMonth;
176 return end_offset;
177 } else {
178 var offset = %DateDaylightSavingsOffset(EquivalentTime(t));
179 if (offset == end_offset) {
180 // The offset at the given time is equal to the offset at the
181 // new end of the interval, so that means that we've just skipped
182 // the point in time where the DST offset change occurred. Updated
183 // the interval to reflect this and reset the increment.
184 cache.start = t;
185 cache.end = new_end;
186 cache.increment = msPerMonth;
187 } else {
188 // The interval contains a DST offset change and the given time is
189 // before it. Adjust the increment to avoid a linear search for
190 // the offset change point and change the end of the interval.
191 cache.increment /= 3;
192 cache.end = t;
193 }
194 // Update the offset in the cache and return it.
195 cache.offset = offset;
196 return offset;
197 }
198 }
145 } 199 }
200
201 // Compute the DST offset for the time and shrink the cache interval
202 // to only contain the time. This allows fast repeated DST offset
203 // computations for the same time.
146 var offset = %DateDaylightSavingsOffset(EquivalentTime(t)); 204 var offset = %DateDaylightSavingsOffset(EquivalentTime(t));
147 daylight_cache_time = t; 205 cache.offset = offset;
148 daylight_cache_offset = offset; 206 cache.start = cache.end = t;
207 cache.increment = msPerMonth;
149 return offset; 208 return offset;
150 } 209 }
151 210
152 211
153 var timezone_cache_time = $NaN; 212 var timezone_cache_time = $NaN;
154 var timezone_cache_timezone; 213 var timezone_cache_timezone;
155 214
156 function LocalTimezone(t) { 215 function LocalTimezone(t) {
157 if(t == timezone_cache_time) { 216 if (t == timezone_cache_time) {
158 return timezone_cache_timezone; 217 return timezone_cache_timezone;
159 } 218 }
160 var timezone = %DateLocalTimezone(EquivalentTime(t)); 219 var timezone = %DateLocalTimezone(EquivalentTime(t));
161 timezone_cache_time = t; 220 timezone_cache_time = t;
162 timezone_cache_timezone = timezone; 221 timezone_cache_timezone = timezone;
163 return timezone; 222 return timezone;
164 } 223 }
165 224
166 225
167 function WeekDay(time) { 226 function WeekDay(time) {
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 "toGMTString", DateToGMTString, 1122 "toGMTString", DateToGMTString,
1064 "toUTCString", DateToUTCString, 1123 "toUTCString", DateToUTCString,
1065 "getYear", DateGetYear, 1124 "getYear", DateGetYear,
1066 "setYear", DateSetYear, 1125 "setYear", DateSetYear,
1067 "toISOString", DateToISOString, 1126 "toISOString", DateToISOString,
1068 "toJSON", DateToJSON 1127 "toJSON", DateToJSON
1069 )); 1128 ));
1070 } 1129 }
1071 1130
1072 SetupDate(); 1131 SetupDate();
OLDNEW
« no previous file with comments | « no previous file | src/macros.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698