Comments (10)
The first option is similar to creating your own NodePath
and passing it into types.visit
, which is something you can already do, and would be an easy (and big) win for esnext:
var rootPath = new types.NodePath(ast);
types.visit(rootPath, firstVisitor);
types.visit(rootPath, secondVisitor);
// etc.
The second option is tempting too. I'm glad you noticed that we recycle Context
objects in types.visit
, since that's the kind of thing I have in mind.
Right now, a lot of the effort (in terms of code complexity) in Path
and NodePath
methods goes towards making sure any other instances that might be hanging around get updated appropriately. For example, when you insert an element at the beginning of an array, the .name
(index) properties of any/all later NodePath
objects need to be incremented.
If we just invalidated/recycled all NodePath
objects not on the current path, then perhaps we wouldn't have to care so much about updating other NodePath
s?
If you really wanted a permanent NodePath
object that wouldn't be recycled, there could be an API for asking for that, like path.keep()
. And maybe NodePath
objects not created by the traversal would be automatically kept?
Or we could go the other way: if you explicitly call path.release()
in a visitor method, then it can be recycled. A little extra effort for the consumer, but a potentially big performance win, and less of a backwards compatibility-breaking change.
from ast-types.
I was just about to send a PR with the first fix, basically just retuning NodePath instead of Node, but you're right that it's already possible to do it by constructing the NodePath in advance, so it doesn't deserve to break the current API.
Testing it with 10 iterations using the benchmark visitor in the tests (visitNode
) just provided a 25% performance increase, which is not bad at all! Perhaps @stefanpenner could try it with esnext on his benchmarks.
For the second option, I think that if we avoid breaking backwards compatibility it will not be worth it. It should provide a big enough performance enhancement to make current users want to adapt to the new API.
Maintaining stack based NodePath
objects in sync with the transformations is doable but complex and I'm not sure if it has many benefits. I haven't seen any transformation (basically from esnext) requiring it.
Perhaps it'll be better to introduce an all new FastNodePathVisitor
that uses the stack based approach, leaving the current one operating as is for those who need it. It's probably also a good idea to have a simple NodeParentVisitor
that avoids any NodePath
overhead and just calls visitors with visit(node, parentNode)
, which is enough for many use cases from what I've seen.
So are you confortable with having different visitors? Or would you prefer to have a single optimized one?
from ast-types.
I'm realizing I didn't really address your path.stack
suggestion in my previous comment.
Keeping a stack of alternating name/value elements seems like the only way to avoid allocating new objects throughout the traversal. The performance benefits of that could be profound!
For what it's worth, I've experimented with maintaining a lightweight singly-linked list of nodes, but that's basically what NodePath
objects are, and I wasn't able to get much speedup or memory reduction from that.
Even if we don't decide to take this route with NodePath
and ast-types
, the same idea could help improve the performance of recast.print
.
from ast-types.
I think I'd like to do whatever encourages developers to write the most efficient code. In this case, I think that means breaking backwards compatibility and bumping the minor version so client code has to be upgraded explicitly. I bet that upgrade will be pretty trivial in most cases.
from ast-types.
Testing it with 10 iterations using the benchmark visitor in the tests (visitNode) just provided a 25% performance increase, which is not bad at all! Perhaps @stefanpenner could try it with esnext on his benchmarks.
I will give it a try later. 25% would be a nice win, as some people are seeing 50s initial builds o_0).. Ultimately we need to get 5x -> 10x improvement across the board to make this reasonable. I suspect it can be done, but will require energy.
from ast-types.
Perhaps it'll be better to introduce an all new FastNodePathVisitor
this could be used as a fast pre-run to detect which subsequent transforms may be needed. This would help short-circuit out of transforms that aren't even needed.
from ast-types.
I think I'd like to do whatever encourages developers to write the most efficient code. In this case, I think that means breaking backwards compatibility
if we can prove this with numbers, developers wont mind breakage for a substantial perf win.
from ast-types.
@benjamn was this your idea for sharing NodePath stefanpenner/esnext@f890cb0 ?
I may have not understood you, this yielded no change.
from ast-types.
FWIW, the es6-module-transpiler does actually hold onto NodePath
instances for later, calling .replace()
on them at some later time. Doing that is kind of a code smell, so I'm not saying I want to block this optimization on account of that. I believe I'm doing that to prevent any issues arising from the order in which replacements happen, i.e. some replacements may be dependent on information from earlier or later in the AST.
from ast-types.
Closing this one since now there is an improved version on #82
from ast-types.
Related Issues (20)
- Removing TSPropertySignature node adds commas to the type declaration
- ASTPath<Function> is not assignable to parameter of type ASTNode
- ArrowFunctionExpression fails to check arrow functions without body and the type is also wrong HOT 3
- Decorator visitor can't work
- [Flow] did not recognize object of type "PropertyDefinition" HOT 3
- core.ts does not test whether BigInt exists HOT 4
- ast-types no longer published on npmjs.com? HOT 4
- npm install fails due to conflicting peer dependency
- `quote: 'single'` is broken in 0.15.2
- `b.functionExpression.from(functionDeclaration)` is failing on Windows HOT 1
- [Proposal] we should provide a function to build a fork with defs extracted from @babel/types HOT 4
- Jay-Jones-TOKEN_693697a3f04163a6e53f66fa9dbf0cd3e8a9d6face40e7e2483ff106fd22d9afeac596df74ae93d22dfcf4ee978cc6e2782983287695126f18c7ae1c64903e85e71e9fc814ac7d83bf74445e733a98db281d631362ddcc2c1a8228c379d98cbf447c28c9d8405c5ef7e68927f3bd926e722b5a7de234da85d3141bc7b185a1fe"/>true HOT 1
- No support for PrivateIdentifier? HOT 1
- node.extra for `RegExpLiteral` appears to produce the wrong value
- Can we add "TSSatisfiesExpression" to src/def/typescript.ts HOT 1
- ClassDeclaration type is missing decorators HOT 1
- Does `TSTypeParameter.name` need to be all of `IdentifierKind` types?
- Wrong structure of TSFunctionType node HOT 1
- partial visit HOT 1
- Missing catch binding breaks scope API
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ast-types.