Skip to content

Commit

Permalink
cache intl objects for 85x speedup
Browse files Browse the repository at this point in the history
  • Loading branch information
icambron committed Nov 3, 2018
1 parent b217dc4 commit bb77d5e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 11 deletions.
3 changes: 3 additions & 0 deletions benchmarks/datetime.js
Expand Up @@ -37,6 +37,9 @@ suite
.add("DateTime#toISO", () => {
dt.toISO();
})
.add("DateTime#toFormatString", () => {
dt.toLocaleString();
})
.on("cycle", event => {
console.log(String(event.target));
})
Expand Down
47 changes: 36 additions & 11 deletions src/impl/locale.js
Expand Up @@ -4,6 +4,28 @@ import Settings from "../settings";
import DateTime from "../datetime";
import Formatter from "./formatter";

let intlDTCache = {};
function getCachedDTF(locString, opts = {}) {
const key = JSON.stringify([locString, opts]);
let dtf = intlDTCache[key];
if (!dtf) {
dtf = new Intl.DateTimeFormat(locString, opts);
intlDTCache[key] = dtf;
}
return dtf;
}

let intlNumCache = {};
function getCachendINF(locString, opts = {}) {
const key = JSON.stringify([locString, opts]);
let inf = intlNumCache[key];
if (!inf) {
inf = new Intl.NumberFormat(locString, opts);
intlNumCache[key] = inf;
}
return inf;
}

let sysLocaleCache = null;
function systemLocale() {
if (sysLocaleCache) {
Expand Down Expand Up @@ -35,9 +57,9 @@ function parseLocaleString(localeStr) {
let options;
const smaller = localeStr.substring(0, uIndex);
try {
options = Intl.DateTimeFormat(localeStr).resolvedOptions();
options = getCachedDTF(localeStr).resolvedOptions();
} catch (e) {
options = Intl.DateTimeFormat(smaller).resolvedOptions();
options = getCachedDTF(smaller).resolvedOptions();
}

const { numberingSystem, calendar } = options;
Expand Down Expand Up @@ -141,12 +163,12 @@ class IntlNumberFormatter {
}

this.floor = opts.floor;
this.intl = new Intl.NumberFormat(intl, intlOpts);
this.inf = getCachendINF(intl, intlOpts);
}

format(i) {
const fixed = this.floor ? Math.floor(i) : i;
return this.intl.format(fixed);
return this.inf.format(fixed);
}
}

Expand Down Expand Up @@ -184,11 +206,11 @@ class PolyDateFormatter {
}

if (this.hasIntl) {
const realIntlOpts = Object.assign({}, this.opts);
const intlOpts = Object.assign({}, this.opts);
if (z) {
realIntlOpts.timeZone = z;
intlOpts.timeZone = z;
}
this.dtf = new Intl.DateTimeFormat(intl, realIntlOpts);
this.dtf = getCachedDTF(intl, intlOpts);
}
}

Expand Down Expand Up @@ -240,11 +262,14 @@ export default class Locale {
localeR = specifiedLocale || (defaultToEN ? "en-US" : systemLocale()),
numberingSystemR = numberingSystem || Settings.defaultNumberingSystem,
outputCalendarR = outputCalendar || Settings.defaultOutputCalendar;

return new Locale(localeR, numberingSystemR, outputCalendarR, specifiedLocale);
}

static resetCache() {
sysLocaleCache = null;
intlDTCache = {};
intlNumCache = {};
}

static fromObject({ locale, numberingSystem, outputCalendar } = {}) {
Expand Down Expand Up @@ -276,7 +301,6 @@ export default class Locale {
return this.fastNumbersCached;
}

// todo: cache me
listingMode(defaultOK = true) {
const intl = hasIntl(),
hasFTP = intl && hasFormatToParts(),
Expand Down Expand Up @@ -358,9 +382,10 @@ export default class Locale {
// for AM and PM. This is probably wrong, but it's makes parsing way easier.
if (!this.meridiemCache) {
const intl = { hour: "numeric", hour12: true };
this.meridiemCache = [DateTime.utc(2016, 11, 13, 9), DateTime.utc(2016, 11, 13, 19)].map(
dt => this.extract(dt, intl, "dayperiod")
);
this.meridiemCache = [
DateTime.utc(2016, 11, 13, 9),
DateTime.utc(2016, 11, 13, 19)
].map(dt => this.extract(dt, intl, "dayperiod"));
}

return this.meridiemCache;
Expand Down

0 comments on commit bb77d5e

Please sign in to comment.