From 744ca8d4393bccfc69c8815a2778f23070d63f22 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Wed, 2 Jun 2021 11:01:23 -0700 Subject: [PATCH] FieldDisplay: add cache to reuse field value calculations (#35072) * add timeline value cache * add timeline value cache * with console logs * cleanup Co-authored-by: Leon Sorokin --- .../grafana-data/src/field/fieldOverrides.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/grafana-data/src/field/fieldOverrides.ts b/packages/grafana-data/src/field/fieldOverrides.ts index 932d934801a..d98f72b165b 100644 --- a/packages/grafana-data/src/field/fieldOverrides.ts +++ b/packages/grafana-data/src/field/fieldOverrides.ts @@ -2,6 +2,8 @@ import { ApplyFieldOverrideOptions, DataFrame, DataLink, + DisplayProcessor, + DisplayValue, DynamicConfigValue, Field, FieldColorModeId, @@ -187,6 +189,11 @@ export function applyFieldOverrides(options: ApplyFieldOverrideOptions): DataFra timeZone: options.timeZone, }); + // Wrap the display with a cache to avoid double calls + if (newField.config.unit !== 'dateTimeFromNow') { + newField.display = cachingDisplayProcessor(newField.display, 2500); + } + // Attach data links supplier newField.getLinks = getLinksSupplier( newFrame, @@ -204,6 +211,24 @@ export function applyFieldOverrides(options: ApplyFieldOverrideOptions): DataFra }); } +function cachingDisplayProcessor(disp: DisplayProcessor, maxCacheSize = 2500): DisplayProcessor { + const cache = new Map(); + + return (value: any) => { + let v = cache.get(value); + if (!v) { + // Don't grow too big + if (cache.size === maxCacheSize) { + cache.clear(); + } + + v = disp(value); + cache.set(value, v); + } + return v; + }; +} + export interface FieldOverrideEnv extends FieldOverrideContext { fieldConfigRegistry: FieldConfigOptionsRegistry; }