From 37aecc8cb94630147882c5bc15dbe14f70d40516 Mon Sep 17 00:00:00 2001 From: Wenjun Xu <906626481@qq.com> Date: Fri, 29 Mar 2024 16:41:15 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20getDimensionValues?= =?UTF-8?q?=20=E5=9C=A8=E5=A4=A7=E9=87=8F=20flatten=20=E6=83=85=E5=86=B5?= =?UTF-8?q?=E4=B8=8B=E7=9A=84=E6=80=A7=E8=83=BD=20(#2640)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 优化 getDimensionValues 在大量 flatten 情况下的性能 * test: 单测修复 --- .../__tests__/unit/facet/pivot-facet-spec.ts | 1 + .../s2-core/src/data-set/pivot-data-set.ts | 17 +++++++++++++- .../src/utils/dataset/pivot-data-set.ts | 22 +++++++++++-------- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/packages/s2-core/__tests__/unit/facet/pivot-facet-spec.ts b/packages/s2-core/__tests__/unit/facet/pivot-facet-spec.ts index 62017ca0b9..1dbab8bf6c 100644 --- a/packages/s2-core/__tests__/unit/facet/pivot-facet-spec.ts +++ b/packages/s2-core/__tests__/unit/facet/pivot-facet-spec.ts @@ -109,6 +109,7 @@ jest.mock('@/data-set/pivot-data-set', () => { getFieldsAndPivotMetaByField: actualPivotDataSet.prototype.getFieldsAndPivotMetaByField, displayFormattedValueMap: new Map(), + dimensionValuesCache: new Map(), }; }), }; diff --git a/packages/s2-core/src/data-set/pivot-data-set.ts b/packages/s2-core/src/data-set/pivot-data-set.ts index 0f32ee3bc7..b8d0bef58c 100644 --- a/packages/s2-core/src/data-set/pivot-data-set.ts +++ b/packages/s2-core/src/data-set/pivot-data-set.ts @@ -78,6 +78,8 @@ export class PivotDataSet extends BaseDataSet { // sorted dimension values public sortedDimensionValues: SortedDimensionValues; + private dimensionValuesCache: Map; + getExistValuesByDataItem(data: DataType, values: string[]) { return getExistValues(data, values); } @@ -95,6 +97,7 @@ export class PivotDataSet extends BaseDataSet { this.sortedDimensionValues = {}; this.rowPivotMeta = new Map(); this.colPivotMeta = new Map(); + this.dimensionValuesCache = new Map(); this.transformIndexesData(this.originData.concat(this.totalData), rows); this.handleDimensionValuesSort(); } @@ -337,6 +340,13 @@ export class PivotDataSet extends BaseDataSet { return []; } + const isGetAllDimensionValues = isEmpty(query); + + // 暂时先对获取某一个维度所有的 labels 这样的场景做缓存处理,因为内部 flatten 逻辑比较耗时 + if (this.dimensionValuesCache.has(field) && isGetAllDimensionValues) { + return this.dimensionValuesCache.get(field); + } + const dimensionValues = transformDimensionsValues( query, dimensions, @@ -352,7 +362,12 @@ export class PivotDataSet extends BaseDataSet { sortedDimensionValues: this.sortedDimensionValues, }); - return uniq(values.map((v) => v.value)); + const result = uniq(values.map((v) => v.value)); + + if (isGetAllDimensionValues) { + this.dimensionValuesCache.set(field, result); + } + return result; } getTotalValue(query: Query, totalStatus?: TotalStatus) { diff --git a/packages/s2-core/src/utils/dataset/pivot-data-set.ts b/packages/s2-core/src/utils/dataset/pivot-data-set.ts index 8e73baa460..786e7813cb 100644 --- a/packages/s2-core/src/utils/dataset/pivot-data-set.ts +++ b/packages/s2-core/src/utils/dataset/pivot-data-set.ts @@ -4,14 +4,12 @@ import { flatMap, forEach, get, - indexOf, intersection, isArray, isEmpty, isNull, last, set, - sortBy, } from 'lodash'; import type { PickEssential } from '../../common/interface/utils'; import { @@ -477,19 +475,25 @@ export function getSatisfiedPivotMetaValues(params: { function flattenMetaValue(list: PivotMetaValue[], field: string) { const allValues = flatMap(list, (metaValue) => { - const values = [...metaValue.children.values()]; - return values.filter( - (v) => + const values: PivotMetaValue[] = []; + for (const v of metaValue.children.values()) { + if ( v.value !== EMPTY_EXTRA_FIELD_PLACEHOLDER && - (queryType === QueryDataType.All ? true : v.value !== TOTAL_VALUE), - ); + (queryType === QueryDataType.All ? true : v.value !== TOTAL_VALUE) + ) { + values.push(v); + } + } + return values; }); if (list.length > 1) { // 从不同父维度中获取的子维度需要再排一次,比如province => city 按照字母倒序,那么在获取了所有 province 的 city 后需要再排一次 const sortedDimensionValue = sortedDimensionValues[field] ?? []; - return sortBy(allValues, (item) => - indexOf(sortedDimensionValue, item.id), + const indexMap = new Map( + sortedDimensionValue.map((id, index) => [id, index]), ); + allValues.sort((a, b) => indexMap.get(a.id) - indexMap.get(b.id)); + return allValues; } return allValues; }