From 343b0619564522d89b56e26b91e0f45300c912f6 Mon Sep 17 00:00:00 2001 From: Ben Hughes Date: Sat, 9 Mar 2024 09:50:16 -0700 Subject: [PATCH] Perf: Use computed offset passed in DateTime constructor (#1576) * Add benchmark for DateTime.local with zone * Use computed offset passed in DateTime constructor All calls to the datetime constructor that pass an offset (o), have just computed that offset (quickDT, fromObject) except for clone(). Clone passes an "old" option to determine whether previous offset can be reused. If we have config.o, but config.old is not set, then we can use o without computing it. This saves an expensive call to zone.offset that duplicates work that was done immediately prior. --- benchmarks/datetime.js | 5 ++++- src/datetime.js | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/benchmarks/datetime.js b/benchmarks/datetime.js index 32839ad2a..f4dffda7b 100644 --- a/benchmarks/datetime.js +++ b/benchmarks/datetime.js @@ -11,7 +11,7 @@ function runDateTimeSuite() { const formatParser = DateTime.buildFormatParser("yyyy/MM/dd HH:mm:ss.SSS"); suite - .add("DateTime.local", () => { + .add("DateTime.now", () => { DateTime.now(); }) .add("DateTime.fromObject with locale", () => { @@ -20,6 +20,9 @@ function runDateTimeSuite() { .add("DateTime.local with numbers", () => { DateTime.local(2017, 5, 15); }) + .add("DateTime.local with numbers and zone", () => { + DateTime.local(2017, 5, 15, 11, 7, 35, { zone: "America/New_York" }); + }) .add("DateTime.fromISO", () => { DateTime.fromISO("1982-05-25T09:10:11.445Z"); }) diff --git a/src/datetime.js b/src/datetime.js index a3dde9525..5314a9b3a 100644 --- a/src/datetime.js +++ b/src/datetime.js @@ -492,7 +492,9 @@ export default class DateTime { if (unchanged) { [c, o] = [config.old.c, config.old.o]; } else { - const ot = zone.offset(this.ts); + // If an offset has been passed and we have not been called from + // clone(), we can trust it and avoid the offset calculation. + const ot = isNumber(config.o) && !config.old ? config.o : zone.offset(this.ts); c = tsToObj(this.ts, ot); invalid = Number.isNaN(c.year) ? new Invalid("invalid input") : null; c = invalid ? null : c;