Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Address graph building performance and memory usage #927

Closed
20 of 29 tasks
MauricioUyaguari opened this issue Mar 9, 2022 · 4 comments
Closed
20 of 29 tasks

RFC: Address graph building performance and memory usage #927

MauricioUyaguari opened this issue Mar 9, 2022 · 4 comments
Assignees
Labels
Component: Graph Manager Issues related to graph processing and management (including interaction with engine server) logic Difficulty: Challenging Studio Core Team Opened by a member of the Studio core team Type: Discussion Type: Enhancement Type: Mega-thread Tracker for multiple related issues Type: Refactor
Milestone

Comments

@MauricioUyaguari
Copy link
Member

MauricioUyaguari commented Mar 9, 2022

Overview

The problem: when loading a huge project, depending on the size, Studio can take several minutes to load or in the worst case, crash the browser. We need to address this problem in, potentially, 3 aspects: performance optimization and memory usage optimization and scale-up resource.

We did some profiling, looks like the perceived performance of graph builder is impacted most visibly by SDLC being slow to return entities and the fact that we introduce mobx when we don't really have to (we could enable mobx when we start change detection instead). We tried to crudely lean down source information coming back in SDLC (using an older project structure) and removing makeObservable in meta models and the graph. This in total boost the perceived performance by 30-35%. This is significant, but not enough as it doesn't really address 2 problems:

  • Users are clueless about what takes so long. We should give more feedback about this so we can improve the perceived performance: i.e. add loading bar with info on loading stages
  • We still build the full graph so it's just the matter of time before users hit the ceiling of memory-usage and crash the browser. So we should address this problem as well. Some ideas include: build partial graph or lazy-build.

Implementation plan

Profiling

  • Turn off mobx in metamodels: timing for graph-building improves 10-20%
  • Turn off source information seems to improve entities loading time 50%: we say "seems" because we test using a different project structure, not on the same project structure and just pruning source information.
  • Compare engine (compilation) and studio (graph-building): apparently, engine is much faster than Studio, Studio performs badly at first phase: deserialize and indexing/initializing, other than that, the performance is somewhat acceptable

Performance optimization

Immediate measure before optimization

Before embarking to improve performance, we should fix the UX by being transparent about the graph builder progress. Hence, we must give better feedback and monitoring around graph-building:

  • Log the build time for steps in better details (for system, dependencies, generation)
  • Produce graph builder report: including step timing and the number of elements
  • Send telemetry about these to monitor the timing
  • During coming back from text-mode or compilation, we probably send telemetry as well

Identify and focus on critical workflow performance optimization

Since we need to optimize around the graph-loading experience, we first should ask the question: What is the purpose of building the graph, is it really the blocker and the pre-requisite for all else? If not, what critical flows can we optimize to improve UX

Taxonomy

For Taxonomy, the critical flow is building datapsace, so we should improve dataspace loading: #936

Query
Studio

For Studio, graph builder serves the purpose of building editor form (analytics and linking) and change detection, as such, we could:

Optimization by deferred/lazy loading

Here we can consider doing something like Pure, where the graph unfolds as we access them. This requires some rewrite at meta level on how we access properties of metamodel. The initial graph is only built partially, only enough to build out the package tree perhaps, then as we access the elements, we start building the graph

More to discuss. Check with @pierredebelen and @kevin-m-knight-gs on how it's been done in Pure

Loading/Saving time optimization

Micro-optimization code

There are micro code-construct which is written in a slightly inefficient manner, but can add-up and hurt performance significantly:

Memory usage optimization

Scale-up resource

Consider using Electron to escape browser's resource limitation - #718: This will also enable us to do more optimization, such as local-file access, SDLC deployment locally (better stability than targeting gitlab)

@github-actions github-actions bot added the Studio Core Team Opened by a member of the Studio core team label Mar 9, 2022
@MauricioUyaguari MauricioUyaguari modified the milestones: 5.0.0, Marathon Mar 9, 2022
@MauricioUyaguari MauricioUyaguari added Component: Graph Manager Issues related to graph processing and management (including interaction with engine server) logic Difficulty: Challenging Type: Refactor Type: Enhancement labels Mar 9, 2022
@akphi akphi changed the title Feature request: Improve Graph Building Performance and Memory leakage Feature request: Improve graph building performance and avoid memory leakage Mar 11, 2022
@akphi
Copy link
Contributor

akphi commented Mar 12, 2022

We should check #257 again after closing this 🤞

@akphi akphi pinned this issue Mar 17, 2022
@akphi akphi changed the title Feature request: Improve graph building performance and avoid memory leakage Discussion: Improve graph building performance and avoid memory leakage Mar 17, 2022
@akphi akphi changed the title Discussion: Improve graph building performance and avoid memory leakage RFC: Address graph building performance and memory usage Mar 17, 2022
@MauricioUyaguari
Copy link
Member Author

MauricioUyaguari commented Mar 18, 2022

@akphi Here are the logs for the 20k, making the change from addUniqueEntry to .push on addChild in Package
packageAddChildrenSlowExample.txt

@akphi
Copy link
Contributor

akphi commented Mar 18, 2022

Thanks to @MauricioUyaguari we have the following comparisons using CDM models (1417) elements:

  • Local Chrome/Engine
    • GRAPH_BUILDER_SYSTEM_BUILT - 178 ms
    • GRAPH_BUILDER_DATA_MODEL_PARSED - 248 ms
    • GRAPH_BUILDER_COMPLETED - 2545 ms
    • GRAPH_INITIALIZED - 2594
    • ENGINE COMPILATION - 151 ms
  • Local Node/Engine
  • GRAPH_BUILDER_SYSTEM_BUILT - 122 ms
  • GRAPH_BUILDER_DATA_MODEL_PARSED - 118 ms
  • GRAPH_BUILDER_COMPLETED - 1686 ms
  • ENGINE COMPILATION - 178ms
  • SDLC Entities as JSON (Project Structure <8) vs Entities as Grammar (Project Structure >= 8) Server https://legend-acct.finos.org
    • SDLC JSON - 1.03s
    • SDLC Grammar - 2.91s
  • SDLC Entities as JSON (Project Structure <8) vs Entities as Grammar (Project Structure >= 8) Server LOCAL
    • SDLC JSON - 899 ms (3.77 MB)
    • SDLC Grammar - 2.33 s (7.26 MB)
    • SDLC Grammar no source information - 2.11 (3.10 MB)

repost since I updated the description of the RFC

@akphi akphi added the Type: Mega-thread Tracker for multiple related issues label Mar 21, 2022
@akphi
Copy link
Contributor

akphi commented Apr 20, 2022

After #1068, I think we can call this satisfactory. The latest stat I got from CDM is

{
  "timings": {
    "GRAPH_INITIALIZED": 799
  },
  "dependencies": {
    "timings": {
      "GRAPH_BUILDER_ELEMENTS_DESERIALIZED": 2,
      "GRAPH_BUILDER_ELEMENTS_INDEXED": 1,
      "GRAPH_BUILDER_SECTION_INDICES_BUILT": 1,
      "GRAPH_BUILDER_DOMAIN_MODELS_BUILT": 0,
      "GRAPH_BUILDER_STORES_BUILT": 1,
      "GRAPH_BUILDER_MAPPINGS_BUILT": 2,
      "GRAPH_BUILDER_CONNECTIONS_AND_RUNTIMES_BUILT": 1,
      "GRAPH_BUILDER_SERVICES_BUILT": 1,
      "GRAPH_BUILDER_OTHER_ELEMENTS_BUILT": 0,
      "GRAPH_BUILDER_COMPLETED": 9,
      "GRAPH_DEPENDENCIES_FETCHED": 11
    },
    "elementCount": {
      "total": 0
    },
    "otherStats": {
      "projectCount": 0
    }
  },
  "graph": {
    "timings": {
      "GRAPH_BUILDER_ELEMENTS_DESERIALIZED": 325,
      "GRAPH_BUILDER_ELEMENTS_INDEXED": 74,
      "GRAPH_BUILDER_SECTION_INDICES_BUILT": 1,
      "GRAPH_BUILDER_DOMAIN_MODELS_BUILT": 336,
      "GRAPH_BUILDER_STORES_BUILT": 1,
      "GRAPH_BUILDER_MAPPINGS_BUILT": 0,
      "GRAPH_BUILDER_CONNECTIONS_AND_RUNTIMES_BUILT": 1,
      "GRAPH_BUILDER_SERVICES_BUILT": 1,
      "GRAPH_BUILDER_OTHER_ELEMENTS_BUILT": 23,
      "GRAPH_BUILDER_COMPLETED": 762
    },
    "elementCount": {
      "total": 1417,
      "other": 2,
      "sectionIndex": 0,
      "association": 0,
      "class": 1045,
      "enumeration": 366,
      "function": 0,
      "profile": 1,
      "measure": 0,
      "store": 0,
      "mapping": 0,
      "connection": 0,
      "runtime": 0,
      "service": 0
    },
    "otherStats": {}
  },
  "generations": {
    "timings": {
      "GRAPH_BUILDER_ELEMENTS_DESERIALIZED": 1,
      "GRAPH_BUILDER_ELEMENTS_INDEXED": 2,
      "GRAPH_BUILDER_SECTION_INDICES_BUILT": 1,
      "GRAPH_BUILDER_DOMAIN_MODELS_BUILT": 1,
      "GRAPH_BUILDER_STORES_BUILT": 1,
      "GRAPH_BUILDER_MAPPINGS_BUILT": 0,
      "GRAPH_BUILDER_CONNECTIONS_AND_RUNTIMES_BUILT": 1,
      "GRAPH_BUILDER_SERVICES_BUILT": 1,
      "GRAPH_BUILDER_OTHER_ELEMENTS_BUILT": 0,
      "GRAPH_BUILDER_COMPLETED": 8
    },
    "elementCount": {
      "total": 0
    },
    "otherStats": {
      "generationCount": 0
    }
  }
}

So we have reduced the times from 8000ms -> ~800ms, that's ~10x improvement. I'd say this is rough number, we do a bunch of caching in several places (which CDM isn't the best to show this improvement), so it might can even go up to ~15x in some case.

This takes a crap load of refactoring, grinding, and fixing bugs. Thanks folks @MauricioUyaguari @YannanGao-gs @gayathrir11 🦄 !!!!

I will close this issue for now as the rest of the optimizations have already have their own threads and can be left in backlog to tackle over time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Graph Manager Issues related to graph processing and management (including interaction with engine server) logic Difficulty: Challenging Studio Core Team Opened by a member of the Studio core team Type: Discussion Type: Enhancement Type: Mega-thread Tracker for multiple related issues Type: Refactor
Projects
None yet
Development

No branches or pull requests

5 participants