-
Notifications
You must be signed in to change notification settings - Fork 368
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: improved performance of formatters (#818)
- Loading branch information
Showing
3 changed files
with
111 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { date, number } from "./formats" | ||
|
||
describe("@lingui/core/formats", () => { | ||
it("number formatter is memoized", async () => { | ||
const firstRunt0 = performance.now() | ||
number("es", {})(10000) | ||
const firstRunt1 = performance.now() | ||
const firstRunResult = firstRunt1 - firstRunt0 | ||
|
||
const seconddRunt0 = performance.now() | ||
number("es", {})(10000) | ||
const seconddRunt1 = performance.now() | ||
const secondRunResult = seconddRunt1 - seconddRunt0 | ||
|
||
expect(secondRunResult).toBeLessThan(firstRunResult) | ||
}) | ||
it("date formatter is memoized", async () => { | ||
const firstRunt0 = performance.now() | ||
date("es", {})(new Date()) | ||
const firstRunt1 = performance.now() | ||
const firstRunResult = firstRunt1 - firstRunt0 | ||
|
||
const seconddRunt0 = performance.now() | ||
date("es", {})(new Date()) | ||
const seconddRunt1 = performance.now() | ||
const secondRunResult = seconddRunt1 - seconddRunt0 | ||
|
||
expect(secondRunResult).toBeLessThan(firstRunResult) | ||
}) | ||
|
||
it("date memoized function is faster than the not memoized function", () => { | ||
const loopt0 = performance.now() | ||
for (let i = 0; i < 1000; i++) { | ||
date("es", {})(new Date()) | ||
} | ||
const loopt1 = performance.now() | ||
const memoizedDateResult = loopt1 - loopt0 | ||
|
||
const loop0 = performance.now() | ||
for (let i = 0; i < 1000; i++) { | ||
date("es", {}, false)(new Date()) | ||
} | ||
const loop1 = performance.now() | ||
const withoutMemoizeResult = loop1 - loop0 | ||
|
||
expect(memoizedDateResult).toBeLessThan(withoutMemoizeResult) | ||
}) | ||
|
||
it("number memoized function is faster than the not memoized function", () => { | ||
const loopt0 = performance.now() | ||
for (let i = 0; i < 1000; i++) { | ||
number("es", {})(999666) | ||
} | ||
const loopt1 = performance.now() | ||
const memoizedNumberResult = loopt1 - loopt0 | ||
|
||
const loop0 = performance.now() | ||
for (let i = 0; i < 1000; i++) { | ||
number("es", {}, false)(999666) | ||
} | ||
const loop1 = performance.now() | ||
const withoutMemoizeResult = loop1 - loop0 | ||
|
||
expect(memoizedNumberResult).toBeLessThan(withoutMemoizeResult) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,60 @@ | ||
import { isString } from "./essentials" | ||
import { Locales } from "./i18n" | ||
|
||
/** Memoized cache */ | ||
const numberFormats = new Map<string, Intl.NumberFormat>() | ||
const dateFormats = new Map<string, Intl.DateTimeFormat>() | ||
|
||
export function date( | ||
locales: Locales, | ||
format: Intl.DateTimeFormatOptions = {} | ||
format: Intl.DateTimeFormatOptions = {}, | ||
memoize: boolean = true, | ||
): (value: string | Date) => string { | ||
const formatter = new Intl.DateTimeFormat(locales, format) | ||
return (value) => { | ||
if (isString(value)) value = new Date(value) | ||
if (memoize) { | ||
const key = cacheKey<Intl.DateTimeFormatOptions>(locales, format) | ||
if (dateFormats.has(key)) { | ||
return dateFormats.get(key).format(value) | ||
} | ||
|
||
const formatter = new Intl.DateTimeFormat(locales, format) | ||
dateFormats.set(key, formatter) | ||
return formatter.format(value) | ||
} | ||
|
||
const formatter = new Intl.DateTimeFormat(locales, format) | ||
return formatter.format(value) | ||
} | ||
} | ||
|
||
export function number( | ||
locales: Locales, | ||
format: Intl.NumberFormatOptions = {} | ||
format: Intl.NumberFormatOptions = {}, | ||
memoize: boolean = true, | ||
): (value: number) => string { | ||
const formatter = new Intl.NumberFormat(locales, format) | ||
return (value) => formatter.format(value) | ||
return (value) => { | ||
if (memoize) { | ||
const key = cacheKey<Intl.NumberFormatOptions>(locales, format) | ||
if (numberFormats.has(key)) { | ||
return numberFormats.get(key).format(value) | ||
} | ||
|
||
const formatter = new Intl.NumberFormat(locales, format) | ||
numberFormats.set(key, formatter) | ||
return formatter.format(value) | ||
} | ||
|
||
const formatter = new Intl.NumberFormat(locales, format) | ||
return formatter.format(value) | ||
} | ||
} | ||
|
||
/** Memoize helpers */ | ||
function cacheKey<T>( | ||
locales?: string | string[], | ||
options: T = {} as T, | ||
) { | ||
const localeKey = Array.isArray(locales) ? locales.sort().join('-') : locales | ||
return `${localeKey}-${JSON.stringify(options)}` | ||
} |
22667ad
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs: