Skip to content

Commit

Permalink
[PERF] evaluation: invalidate spreading in batch
Browse files Browse the repository at this point in the history
When spreading the result of an array formula, we invalidate formulas
depending on the spread zone. Currently, we look for the dependencies
one position in the spread zone at a time.

It's much more efficient to group all those individual positions in zones
and call `this.getCellsDependingOn(...)` with those zones.

This commit reduces the time to evaluate the large array formula
dataset from 60+ seconds to ~36 seconds.

Task: 4036899
Part-of: #4589
Signed-off-by: Vincent Schippefilt (vsc) <[email protected]>
  • Loading branch information
LucasLefevre committed Jul 5, 2024
1 parent c98b193 commit 08d7226
Showing 1 changed file with 30 additions and 5 deletions.
35 changes: 30 additions & 5 deletions src/plugins/ui_core_views/cell_evaluation/evaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,13 +314,42 @@ export class Evaluator {
// thanks to the isMatrix check above, we know that formulaReturn is MatrixFunctionReturn
this.spreadValues(formulaPosition, formulaReturn)
);

this.invalidatePositionsDependingOnSpread(formulaPosition, nbColumns, nbRows);
return createEvaluatedCell(formulaReturn[0][0].value, {
format: cellData.format || formulaReturn[0][0]?.format,
locale: this.getters.getLocale(),
});
}

private invalidatePositionsDependingOnSpread(
arrayFormulaPosition: CellPosition,
nbColumns: number,
nbRows: number
) {
// the result matrix is split in 2 zones to exclude the array formula position
const top = arrayFormulaPosition.row;
const left = arrayFormulaPosition.col;
const bottom = top + nbRows - 1;
const leftColumnZone = {
top: top + 1,
bottom,
left,
right: left,
};
const rightPartZone = {
top,
bottom,
left: left + 1,
right: left + nbColumns - 1,
};
const sheetId = arrayFormulaPosition.sheetId;
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn([
{ sheetId, zone: rightPartZone },
{ sheetId, zone: leftColumnZone },
]);
this.nextPositionsToUpdate.addMany(invalidatedPositions);
}

private assertSheetHasEnoughSpaceToSpreadFormulaResult(
{ sheetId, col, row }: CellPosition,
matrixResult: Matrix<ValueAndFormat>
Expand Down Expand Up @@ -397,10 +426,6 @@ export class Evaluator {
const positionId = this.encoder.encode(position);

this.setEvaluatedCell(positionId, evaluatedCell);

// check if formula dependencies present in the spread zone
// if so, they need to be recomputed
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([positionId]));
};
}

Expand Down

0 comments on commit 08d7226

Please sign in to comment.