Skip to content

Commit

Permalink
[PERF] evaluation: faster dependencies checking
Browse files Browse the repository at this point in the history
This commit improves the performance of a pathological case of the
dependency finding algorithm.

Let's say
All cells in column B depends on A1 (each cell in B contains a
formula referencing A1).
All cells in column C depends on every cell in B

What happens when we update A1: the first `while` iteration finds all cells in
B, which are pushed in the process queue (B1, B2, B3, B4, ...).
At the next iteration, the code searches for the dependencies of B1 and adds them
to the queue (now B2, B3, B4, ..., C1, C2, C3, ...)
The next iteration, we search for the dependencies of B2 which are again
C1, C2, C3,... They are not pushed to the queue because we already visited
them, but we still have to process them.
Next is the dependencies of B3...again C1, C2, C3, ...

We process over and over again the same positions.

With this commit, we no longer process individual positions one after the other.
We first group positions in bigger zones. With the example above, we would
have grouped B1, B2, B3, ... into a single zone with the the entire B column.
Hence we do a single `this.rTree.search` rather one per position.

On RNG's spreadsheet, `getCellsDependingOn` total time goes from 12+ secondes
to <180ms, (~90% to ~10%) when updating certain cells with the describe
dependency configuration.

closes #4125

Task: 3874821
Signed-off-by: Rémi Rahir (rar) <[email protected]>
  • Loading branch information
LucasLefevre authored and rrahir committed Apr 24, 2024
1 parent 4de08fa commit 466b074
Showing 1 changed file with 11 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { positions, positionToZone } from "../../../helpers";
import { CellPosition } from "../../../types";
import { recomputeZones } from "../../../helpers/recompute_zones";
import { CellPosition, UID, Zone } from "../../../types";
import { PositionMap } from "./position_map";
import { PositionSet } from "./position_set";
import { RTreeBoundingBox, RTreeItem, SpreadsheetRTree } from "./r_tree";
Expand Down Expand Up @@ -67,11 +68,19 @@ export class FormulaDependencyGraph {
);

const impactedPositions = this.rTree.search(range).map((dep) => dep.data);
const nextInQueue: Record<UID, Zone[]> = {};
for (const position of impactedPositions) {
if (!visited.has(position)) {
queue.push({ sheetId: position.sheetId, zone: positionToZone(position) });
if (!nextInQueue[position.sheetId]) {
nextInQueue[position.sheetId] = [];
}
nextInQueue[position.sheetId].push(positionToZone(position));
}
}
for (const sheetId in nextInQueue) {
const zones = recomputeZones(nextInQueue[sheetId], []);
queue.push(...zones.map((zone) => ({ sheetId, zone })));
}
}
visited.deleteMany(
ranges.flatMap((r) =>
Expand Down

0 comments on commit 466b074

Please sign in to comment.