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

ApiDOM performance whitepaper #385

Open
7 of 10 tasks
char0n opened this issue Apr 28, 2021 · 0 comments
Open
7 of 10 tasks

ApiDOM performance whitepaper #385

char0n opened this issue Apr 28, 2021 · 0 comments
Labels
ApiDOM enhancement New feature or request

Comments

@char0n
Copy link
Member

char0n commented Apr 28, 2021

This paper serves as a whitepaper for feasible performance optimizations proposals which can be performed on ApiDOM monorepo. Paper is divided into sections (single top level section represents one monorepo package) and each of these sections is further divided into sub-sections describing the actual performance optimization proposal.

Paper also contains references to various revisions. Keep in mind that code can change between specific revision and master branch as time goes on. This can render certain performance optimization proposal invalid.

apidom

Transcluder

For every use of transclude function all the parent edges needs to be computed.

Single transclution

It is more optimal to use single traversal run for this usecase. As soon as search element is found, it is transcluded with replace element and traversal is immediately stopped.

Multi transclution

This is a usecase where multiple search elements needs to be replaced by multiple replace elements. Again it is more optimal to use traversal to replace/transclude the nodes.

Repeated transclution

This is more a corner case - we want to transclude one or multiple elements during different points in time on the same ApiDOM structure. It's possible to use current implementation of transclution to cover this usecase.

All the fore-mentioned usecases are currently embedded in one single implementation which makes it less then optimal.

apidom-ast

Parallel visiting

Parallel visiting or megring of the visitors is implemented in a way where all the "merged" visitors are iterated in every enter or leave visitor function and appropriate visitFn is obtained and executed. This can be implemented in more performant way where static chain of visitor functions is constructed by merging the visitors before they're executed.

Parallel visiting (merging) is used in refractor layers in all the namespace packages.

apidom-ns-asyncapi-2-0

Refracting primitive fields

During refracting phase traversal is executed on every field of every Object Element or item of Array Element. This has potentially significant performance implications. We could device a more performant mechanism (let's call it visitor-shortcut) that would not run traversal on any field that we expect is going to be a primitive or generic element (String Element, Number Element, Object Element, etc...). Instead fields like those are going to be directly translated from generic form to semantic form by simple cloning.

Refracting primitive fields - utilize specification object

Currently every primitive field has it's own file even though it's using generic FallbackVisitor. We can eliminate those files and attach visitors directly in specification objects. By this we will save a lot of code and file imports and lower the overall size of resulting UMD bundles.

Refractor plugins

If refractor plugins are utilized, they require additional full traversal after the refracting phase has finished. It would be convenient to run refractor plugins without additional full traversal. Running plugins inside refracting phase is not feasible as refraction transforms generic ApiDOM into semantic progressively. If we would run refractor plugins inside refracting phase it would mean that plugins will receive either generic ApiDOM elements or semantic ones depending on the state of refracting at the point of refractor plugin intercepting it. One feasible solution would be to fold our build-in defaults plugins into refracting phase directly and if there would be need for additional ad-hoc plugins, person that attaches them to refractor must expect that there will be performance implication.

apidom-ns-openapi-3-1

Refracting primitive fields

During refracting phase traversal is executed on every field of every Object Element or item of Array Element. This has potentially significant performance implications. We could device a more performant mechanism (let's call it visitor-shortcut) that would not run traversal on any field that we expect is going to be a primitive or generic element (String Element, Number Element, Object Element, etc...). Instead fields like those are going to be directly translated from generic form to semantic form by simple cloning.

Refracting primitive fields - utilize specification object

Currently every primitive field has it's own file even though it's using generic FallbackVisitor. We can eliminate those files and attach visitors directly in specification objects. By this we will save a lot of code and file imports and lower the overall size of resulting UMD bundles.

Refractor plugins

If refractor plugins are utilized, they require additional full traversal after the refracting phase has finished. It would be convenient to run refractor plugins without additional full traversal. Running plugins inside refracting phase is not feasible as refraction transforms generic ApiDOM into semantic progressively. If we would run refractor plugins inside refracting phase it would mean that plugins will receive either generic ApiDOM elements or semantic ones depending on the state of refracting at the point of refractor plugin intercepting it. One feasible solution would be to fold our build-in defaults plugins into refracting phase directly and if there would be need for additional ad-hoc plugins, person that attaches them to refractor must expect that there will be performance implication.

apidom-parser

No feasible performance optimization are currently proposed for this package.

apidom-parser-adapter-json

Syntactical analysis

In order to parse source JSON string into generic ApiDOM following parsing phases are peformed:

  1. Lexical analysis (tree-sitter)

Source JSON string is parsed and tokenized. The result of these operations is a structure that technically categorizes as CST, but contains further APIs for AST like manipulation.

  1. Syntactical analysis

CST is transformed into JSON AST.

  1. Transform

During this phase JSON AST is transformed into generic ApiDOM.

We could possibly fold phase 2. and 3. into a single phase. By doing this we would avoid one full traversal and maintaining additional JSON AST structure in memory. Syntactical analysis phase doesn't contain any additional logic that couldn't be folded easily into Transform phase because JSON is very simple format to process.

apidom-parser-adapter-yaml-1-2

Syntactical analysis

In order to parse source YAML 1.2 string into generic ApiDOM following parsing phases are peformed:

  1. Lexical analysis (tree-sitter)

Source YAML string is parsed and tokenized. The result of these operations is a structure that technically categorizes as CST, but contains further APIs for AST like manipulation.

  1. Syntactical analysis

CST is transformed into YAML AST. These transformations includes resolving YAML anchors, processing YAML Schemas and creating surrogate AST nodes wherever they're missing.

  1. Transform

During this phase YAML AST is transformed into generic ApiDOM.

We could possibly fold phase 2. and 3. into a single phase. By doing this we would avoid one full traversal and maintaining additional YAML AST structure in memory. Unfortunately YAML 1.2 is pretty complex and folding the two phases would create complex code that would not be easy to maintain. IMHO in this case code readability and maintenance wins over performance. It is always possible to create additional YAML 1.2 adapter with folded phases in future.

apidom-parser-adapter-asyncapi-json-2-0

This is a hollow adapter composed of two main packages: apidom-parser-adapter-json and apidom-ns-asyncapi-2-0. All the performance optimizations that will be performed on these two main packages will inevitably increase performance of this adapter.

This adapter goes through following phases:

  1. Lexical analysis
  2. Syntactical analysis
  3. Transform
  4. Refracting

It's possible to create a super performant version of this adapter folding all the aforementioned phases into single one.

Transclution

We could avoid transclusion here completely or use one of the already optimized transcluder described in this paper.

apidom-parser-adapter-asyncapi-yaml-2-0

This is a hollow adapter composed of two main packages: apidom-parser-adapter-yaml-1-2 and apidom-ns-asyncapi-2-0. All the performance optimizations that will be performed on these two main packages will inevitably increase performance of this adapter.

This adapter goes through following phases:

  1. Lexical analysis
  2. Syntactical analysis
  3. Transform
  4. Refracting

It's possible to create a super performant version of this adapter folding all the aforementioned phases into single one.

Transclution

We could avoid transclusion here completely or use one of the already optimized transcluder described in this paper.

apidom-parser-adapter-openapi-json-3-1

This is a hollow adapter composed of two main packages: apidom-parser-adapter-json and apidom-ns-openapi-3-1. All the performance optimizations that will be performed on these two main packages will inevitably increase performance of this adapter.

This adapter goes through following phases:

  1. Lexical analysis
  2. Syntactical analysis
  3. Transform
  4. Refracting

It's possible to create a super performant version of this adapter folding all the aforementioned phases into single one.

Transclution

We could avoid transclusion here completely or use one of the already optimized transcluder described in this paper.

apidom-parser-adapter-openapi-yaml-3-1

This is a hollow adapter composed of two main packages: apidom-parser-adapter-yaml-1-2 and apidom-ns-openapi-3-1. All the performance optimizations that will be performed on these two main packages will inevitably increase performance of this adapter.

This adapter goes through following phases:

  1. Lexical analysis
  2. Syntactical analysis
  3. Transform
  4. Refracting

It's possible to create a super performant version of this adapter folding all the aforementioned phases into single one.

Transclution

We could avoid transclusion here completely or use one of the already optimized transcluder described in this paper.

apidom-reference

No feasible performance optimization are currently proposed for this package. The performance and optimal memory management were kept in check during all implementations.

Performance analytics

All performance analytics are performed using benchmark.js library. This library contains proper statistical model for performing analysis.

Resources

Performance optimizations

@char0n char0n added enhancement New feature or request ApiDOM labels Apr 28, 2021
@char0n char0n self-assigned this Apr 28, 2021
@char0n char0n changed the title Creates not about possible optimizations and performance Creates notes about possible optimizations and performance Apr 29, 2021
@char0n char0n changed the title Creates notes about possible optimizations and performance ApiDOM performance whitepaper May 4, 2021
@char0n char0n removed their assignment Dec 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ApiDOM enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant