-
-
Notifications
You must be signed in to change notification settings - Fork 503
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(parser/napi): add flexbuffer to AST transfer (2x speedup) (#1680)
Hi! I have created a proof of concept of improving using oxc in JavaScript. The method is not polished but it provides valuable insights for future direction! Feel free to close~ It is for reference only :) # Context This is a proof of concept implementation of passing binary AST to JavaScript. JavaScript can selectively read flexbuffers-based AST nodes on demand to avoid the deserialization toll. More context [here](https://dev.to/herrington_darkholme/benchmark-typescript-parsers-demystify-rust-tooling-performance-2go8). # Changes * Add a `parseSyncBuffer` napi method to return a binary AST from Rust to JavaScript. The AST is in flexbuffer format. * Add a `test_buffer.js` to test usage of flexbuffers in JavaScript. It is in cjs format because flexbuffers does not support ESM :/ # Result Some preliminary results, for reference only. ``` ~ node test_buffer.js testJSON: 4.043s testBuffer: 2.395s ``` Buffer based API is 100% faster than JSON. # Future Ideas * Flexbuffers itself is slow. A better binary protocol is desired! * Using binary reader to traverse AST is undesirable. A proxy-based API to emulate object behavior will be nice.
- Loading branch information
1 parent
37d5152
commit c63f512
Showing
8 changed files
with
148 additions
and
2 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
const oxc = require('./index'); | ||
const assert = require('assert'); | ||
const flexbuffers = require('flatbuffers/js/flexbuffers'); | ||
const file = require('fs').readFileSync(__dirname + '/index.js', 'utf8'); | ||
|
||
function testBuffer() { | ||
const buffer = oxc.parseSyncBuffer(file); | ||
const ref = flexbuffers.toReference(buffer.buffer); | ||
assert(ref.isMap()); | ||
assert.equal(ref.get('type').stringValue(), 'Program'); | ||
const body = ref.get('body'); | ||
assert(body.isVector()); | ||
} | ||
|
||
function testJSON() { | ||
const ret = oxc.parseSync(file); | ||
const program = JSON.parse(ret.program); | ||
assert(typeof program === 'object'); | ||
assert.equal(program.type, 'Program'); | ||
assert(Array.isArray(program.body)); | ||
} | ||
|
||
function benchmark(func, time) { | ||
console.time(func.name); | ||
for (let i = 0; i < time; i++) { | ||
func(); | ||
} | ||
console.timeEnd(func.name) | ||
} | ||
|
||
benchmark(testJSON, 10000); | ||
benchmark(testBuffer, 10000); |