Skip to content

Commit 0ad464b

Browse files
refactor: modified ymdFromEpochDays to remove allocations
1 parent b7ac6bd commit 0ad464b

File tree

2 files changed

+444
-600
lines changed

2 files changed

+444
-600
lines changed

std/assembly/date.ts

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,18 @@ export class Date {
7474
}
7575

7676
getUTCFullYear(): i32 {
77-
return ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY)).year;
77+
ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY));
78+
return year;
7879
}
7980

8081
getUTCMonth(): i32 {
81-
return ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY)).month - 1;
82+
ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY));
83+
return month - 1;
8284
}
8385

8486
getUTCDate(): i32 {
85-
return ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY)).day;
87+
ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY));
88+
return day;
8689
}
8790

8891
getUTCHours(): i32 {
@@ -121,43 +124,42 @@ export class Date {
121124
}
122125

123126
setUTCDate(value: i32): void {
124-
const ymd = ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY));
125-
throwIfNotInRange(value, 1, lastDayOfMonth(ymd.year, ymd.month));
127+
ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY));
128+
throwIfNotInRange(value, 1, lastDayOfMonth(year, month));
126129
const mills = this.epochMillis % MILLIS_PER_DAY;
127130
this.epochMillis =
128-
i64(daysSinceEpoch(ymd.year, ymd.month, value)) * MILLIS_PER_DAY + mills;
131+
i64(daysSinceEpoch(year, month, value)) * MILLIS_PER_DAY + mills;
129132
}
130133

131134
setUTCMonth(value: i32): void {
132135
throwIfNotInRange(value, 1, 12);
133-
const ymd = ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY));
136+
ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY));
134137
const mills = this.epochMillis % MILLIS_PER_DAY;
135138
this.epochMillis =
136-
i64(daysSinceEpoch(ymd.year, value + 1, ymd.day)) * MILLIS_PER_DAY +
137-
mills;
139+
i64(daysSinceEpoch(year, value + 1, day)) * MILLIS_PER_DAY + mills;
138140
}
139141

140142
setUTCFullYear(value: i32): void {
141-
const ymd = ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY));
143+
ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY));
142144
const mills = this.epochMillis % MILLIS_PER_DAY;
143145
this.epochMillis =
144-
i64(daysSinceEpoch(value, ymd.month, ymd.day)) * MILLIS_PER_DAY + mills;
146+
i64(daysSinceEpoch(value, month, day)) * MILLIS_PER_DAY + mills;
145147
}
146148

147149
toISOString(): string {
148-
const ymd = ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY));
150+
ymdFromEpochDays(i32(this.epochMillis / MILLIS_PER_DAY));
149151

150-
let yearStr = ymd.year.toString();
152+
let yearStr = year.toString();
151153
if (yearStr.length > 4) {
152154
yearStr = "+" + yearStr.padStart(6, "0");
153155
}
154156

155157
return (
156158
yearStr +
157159
"-" +
158-
ymd.month.toString().padStart(2, "0") +
160+
month.toString().padStart(2, "0") +
159161
"-" +
160-
ymd.day.toString().padStart(2, "0") +
162+
day.toString().padStart(2, "0") +
161163
"T" +
162164
this.getUTCHours().toString().padStart(2, "0") +
163165
":" +
@@ -198,12 +200,6 @@ const MILLIS_PER_HOUR = 1_000 * 60 * 60;
198200
const MILLIS_PER_MINUTE = 1_000 * 60;
199201
const MILLIS_PER_SECOND = 1_000;
200202

201-
class YMD {
202-
year: i32;
203-
month: i32;
204-
day: i32;
205-
}
206-
207203
// http://howardhinnant.github.io/date_algorithms.html#is_leap
208204
function isLeap(y: i32): bool {
209205
return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
@@ -220,22 +216,20 @@ function lastDayOfMonth(y: i32, m: i32): i32 {
220216
return m != 2 || !isLeap(y) ? lastDayOfMonthNonLeapYear(m) : 29;
221217
}
222218

219+
// ymdFromEpochDays returns values via globals to avoid allocations
220+
let year: i32, month: i32, day: i32;
223221
// see: http://howardhinnant.github.io/date_algorithms.html#civil_from_days
224-
function ymdFromEpochDays(z: i32): YMD {
222+
function ymdFromEpochDays(z: i32): void {
225223
z += 719468;
226224
const era = (z >= 0 ? z : z - 146096) / 146097;
227225
const doe = z - era * 146097; // [0, 146096]
228226
const yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399]
229-
const y = yoe + era * 400;
227+
year = yoe + era * 400;
230228
const doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365]
231229
const mp = (5 * doy + 2) / 153; // [0, 11]
232-
const d = doy - (153 * mp + 2) / 5 + 1; // [1, 31]
233-
const m = mp + (mp < 10 ? 3 : -9); // [1, 12]
234-
return {
235-
year: y + (m <= 2 ? 1 : 0),
236-
month: m,
237-
day: d,
238-
};
230+
day = doy - (153 * mp + 2) / 5 + 1; // [1, 31]
231+
month = mp + (mp < 10 ? 3 : -9); // [1, 12]
232+
year += (month <= 2 ? 1 : 0);
239233
}
240234

241235
// http://howardhinnant.github.io/date_algorithms.html#days_from_civil

0 commit comments

Comments
 (0)