[Perf] Use cache for getFirstLetters

This commit is contained in:
Alexander Zinchuk 2022-03-19 21:18:59 +01:00
parent ebb6f710d9
commit f51da38631
3 changed files with 35 additions and 16 deletions

View File

@ -1,4 +1,5 @@
import { LangFn } from '../hooks/useLang'; import { LangFn } from '../hooks/useLang';
import withCache from './withCache';
const WEEKDAYS_FULL = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; const WEEKDAYS_FULL = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
const MONTHS_FULL = [ const MONTHS_FULL = [
@ -246,18 +247,8 @@ export function formatVoiceRecordDuration(durationInMs: number) {
return `${parts.join(':')},${String(milliseconds).padStart(2, '0')}`; return `${parts.join(':')},${String(milliseconds).padStart(2, '0')}`;
} }
// `toLocaleString` is slow so we use cache const formatDayToStringWithCache = withCache((dayStartAt: number, locale: string) => {
const dateFormatCache = new Map<string, string>(); return new Date(dayStartAt).toLocaleString(
export function formatDateToString(datetime: Date | number, locale = 'en-US') {
const date = typeof datetime === 'number' ? new Date(datetime) : datetime;
const cacheKey = `${locale}_${getDayStartAt(date)}`;
const cached = dateFormatCache.get(cacheKey);
if (cached) {
return cached;
}
const newValue = date.toLocaleString(
locale, locale,
{ {
year: 'numeric', year: 'numeric',
@ -265,10 +256,13 @@ export function formatDateToString(datetime: Date | number, locale = 'en-US') {
day: 'numeric', day: 'numeric',
}, },
); );
});
dateFormatCache.set(cacheKey, newValue); export function formatDateToString(datetime: Date | number, locale = 'en-US') {
const date = typeof datetime === 'number' ? new Date(datetime) : datetime;
const dayStartAt = getDayStartAt(date);
return newValue; return formatDayToStringWithCache(dayStartAt, locale);
} }
export function formatDateTimeToString(datetime: Date | number, locale = 'en-US') { export function formatDateTimeToString(datetime: Date | number, locale = 'en-US') {

View File

@ -1,5 +1,6 @@
import EMOJI_REGEX from '../lib/twemojiRegex'; import EMOJI_REGEX from '../lib/twemojiRegex';
import { fixNonStandardEmoji } from './emoji'; import { fixNonStandardEmoji } from './emoji';
import withCache from './withCache';
export function formatInteger(value: number) { export function formatInteger(value: number) {
return String(value).replace(/\d(?=(\d{3})+$)/g, '$& '); return String(value).replace(/\d(?=(\d{3})+$)/g, '$& ');
@ -26,7 +27,7 @@ export function formatIntegerCompact(views: number) {
return `${formatFixedNumber(views / 1e6)}M`; return `${formatFixedNumber(views / 1e6)}M`;
} }
export function getFirstLetters(phrase: string, count = 2) { export const getFirstLetters = withCache((phrase: string, count = 2) => {
return phrase return phrase
.replace(/[.,!@#$%^&*()_+=\-`~[\]/\\{}:"|<>?]+/gi, '') .replace(/[.,!@#$%^&*()_+=\-`~[\]/\\{}:"|<>?]+/gi, '')
.trim() .trim()
@ -42,4 +43,4 @@ export function getFirstLetters(phrase: string, count = 2) {
return word.match(/./u)![0].toUpperCase(); return word.match(/./u)![0].toUpperCase();
}) })
.join(''); .join('');
} });

24
src/util/withCache.ts Normal file
View File

@ -0,0 +1,24 @@
const cache = new WeakMap<AnyFunction, Map<string, any>>();
export default function withCache<T extends AnyFunction>(fn: T) {
return (...args: Parameters<T>): ReturnType<T> => {
let fnCache = cache.get(fn);
const cacheKey = args.map(String).join('_');
if (fnCache) {
const cached = fnCache.get(cacheKey);
if (cached) {
return cached;
}
} else {
fnCache = new Map();
cache.set(fn, fnCache);
}
const newValue = fn(...args);
fnCache.set(cacheKey, newValue);
return newValue;
};
}