oxc/napi/parser/test_buffer.js
Herrington Darkholme c63f5123b3
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.
2023-12-15 02:52:33 +00:00

32 lines
888 B
JavaScript

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);