Skip to content

Commit

Permalink
[IMP] evaluation: lazy build dependency graph
Browse files Browse the repository at this point in the history
With this commit, the dependency graph is build lazily.

The cost of building the graph is only paid:
- at the first update
- if there is an array formulas, which shouldn't be most basic spreadsheets

With this, loading the large formula data set (260k cells) is ~20% faster

Before: 4241ms
After: 3457ms
(average of 5 runs)

closes #2090

Signed-off-by: Lucas Lefèvre (lul) <lul@odoo.com>
  • Loading branch information
LucasLefevre committed May 25, 2023
1 parent 0a6a786 commit d01251d
Showing 1 changed file with 13 additions and 10 deletions.
23 changes: 13 additions & 10 deletions src/plugins/ui_core_views/cell_evaluation/evaluator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { forEachPositionsInZone, JetSet, toXC } from "../../../helpers";
import { forEachPositionsInZone, JetSet, lazy, toXC } from "../../../helpers";
import { createEvaluatedCell, errorCell, evaluateLiteral } from "../../../helpers/cells";
import { ModelConfig } from "../../../model";
import { _lt } from "../../../translation";
Expand Down Expand Up @@ -44,7 +44,7 @@ export class Evaluator {
private readonly positionEncoder = new PositionBitsEncoder();

private evaluatedCells: PositionDict<EvaluatedCell> = new Map();
private formulaDependencies = new FormulaDependencyGraph();
private formulaDependencies = lazy(new FormulaDependencyGraph());
private blockedArrayFormulas = new Set<PositionId>();
private spreadingRelations = new SpreadingRelation();

Expand Down Expand Up @@ -81,9 +81,9 @@ export class Evaluator {

updateDependencies(position: CellPosition) {
const positionId = this.encodePosition(position);
this.formulaDependencies.removeAllDependencies(positionId);
this.formulaDependencies().removeAllDependencies(positionId);
const dependencies = this.getDirectDependencies(positionId);
this.formulaDependencies.addDependencies(positionId, dependencies);
this.formulaDependencies().addDependencies(positionId, dependencies);
}

evaluateCells(positions: CellPosition[]) {
Expand Down Expand Up @@ -117,13 +117,16 @@ export class Evaluator {
}

buildDependencyGraph() {
this.formulaDependencies = new FormulaDependencyGraph();
this.blockedArrayFormulas = new Set<PositionId>();
this.spreadingRelations = new SpreadingRelation();
for (const positionId of this.getAllCells()) {
const dependencies = this.getDirectDependencies(positionId);
this.formulaDependencies.addDependencies(positionId, dependencies);
}
this.formulaDependencies = lazy(() => {
const dependencyGraph = new FormulaDependencyGraph();
for (const positionId of this.getAllCells()) {
const dependencies = this.getDirectDependencies(positionId);
dependencyGraph.addDependencies(positionId, dependencies);
}
return dependencyGraph;
});
}

evaluateAllCells() {
Expand Down Expand Up @@ -394,7 +397,7 @@ export class Evaluator {
}

private getCellsDependingOn(positionIds: Iterable<PositionId>): Iterable<PositionId> {
return this.formulaDependencies.getCellsDependingOn(positionIds);
return this.formulaDependencies().getCellsDependingOn(positionIds);
}

private getCell(positionId: PositionId): Cell | undefined {
Expand Down

0 comments on commit d01251d

Please sign in to comment.