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 #4116

Task: 3874821
X-original-commit: b0e0ff3
Signed-off-by: Rémi Rahir (rar) <rar@odoo.com>
  • Loading branch information
LucasLefevre committed Apr 23, 2024
1 parent 9d73856 commit a54fa7f
Showing 1 changed file with 12 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { JetSet } from "../../../helpers";
import { futureRecomputeZones } from "../../../helpers/recompute_zones";
import { UID, Zone } from "../../../types";
import { PositionBitsEncoder, PositionId } from "./evaluator";
import { RTreeBoundingBox, RTreeItem, SpreadsheetRTree } from "./r_tree";

Expand Down Expand Up @@ -61,11 +63,20 @@ export class FormulaDependencyGraph {
visited.addMany(this.encoder.encodeBoundingBox(range));

const impactedPositionIds = this.rTree.search(range).map((dep) => dep.data);
const nextInQueue: Record<UID, Zone[]> = {};
for (const positionId of impactedPositionIds) {
if (!visited.has(positionId)) {
queue.push(this.encoder.decodeToBoundingBox(positionId));
const { sheetId, zone } = this.encoder.decodeToBoundingBox(positionId);
if (!nextInQueue[sheetId]) {
nextInQueue[sheetId] = [];
}
nextInQueue[sheetId].push(zone);
}
}
for (const sheetId in nextInQueue) {
const zones = futureRecomputeZones(nextInQueue[sheetId]);
queue.push(...zones.map((zone) => ({ sheetId, zone })));
}
}
visited.deleteMany(ranges.flatMap((r) => this.encoder.encodeBoundingBox(r)));
return visited;
Expand Down

0 comments on commit a54fa7f

Please sign in to comment.