mateuszradomski / fast-solidity-parser

Solidity parser with tens of megabytes throughput
MIT License
5 stars 0 forks source link

Fast Solidity Parser

A fast library for parsing Solidity with modular architecture allowing for easy integration into any language. Initially written to be a faster @solidity-parser/parser.

Available backends:

Architecture

The parser is divided into two parts: engine and deserializer. Engine is written in C, it takes Solidity source as input and produces an AST encoded as a custom binary format. Deserializer is written in any language that wishes to incorporate the parser. Take for example the JavaScript integration. The engine is compiled into WASM and later called by a wrapper that redirects the binary stream into a deserializer.

Performance

Tested on M2 Pro, 16GB RAM, no battery saver, Node V16.20.1, 15 runs back-to-back, the result is the average of the runs. In the table this library is referred to as FSF while the @solidity-parser/parser is denoted as ASP.

| File size |        ASP |       FSP | Speedup |
|-----------|------------|-----------|---------|
|      7 KB | 685.9 KB/s | 43.2 MB/s |   x62.9 |
|     20 KB | 617.7 KB/s | 57.4 MB/s |   x92.9 |
|    103 KB | 644.5 KB/s | 95.6 MB/s |  x148.3 |
|   1249 KB |   434 KB/s | 56.4 MB/s |  x129.9 |

A few notes about the performance numbers presented above. Please keep in mind that your mileage may vary when it comes to the amount of speed up you're going to perceive. The observed throughput varies a lot from run to run because of garbage collection which is a problem at these kind of speeds. After the first run, each next increases the throughput as the optimizer in V8 kicks in, it takes around 5 runs for it to JIT the entire deserializer.

Size

The entire WASM module is inlined during the build step so there is no need for reading from disk or fetching to initialize the module. The first call suffers a penalty, because the module initialization is performed if it hasn't been done before. On the setup described above the penalty has been measured to be around 1.5ms. Keep in mind that every subsequent call does not suffer this penalty.

|          Kind |   ASP |   FSP | Ratio |
|---------------|-------|-------|-------|
| minify + gzip |  76KB |  36KB |  48%  |
| minify        | 362KB | 267KB |  74%  |
| raw           | 865KB | 385KB |  45%  |

Original @solidity-parser/parser compatibility

The API is very similar as the one exposed be the ANTLR parser. We support range but a decision has been made to drop support for loc in favor of performance. You can easily emulate this using the range output if you really need it.

The resulting AST object is identical to the one produced by @solidity-parser/parser beside the exceptions listed below:

Stuff that is not yet supported

Stuff that @solidity-parser/parser will accept but is invalid

Stuff that @solidity-parser/parser will not accept but is valid

Stuff that @solidity-parser/parser parses wrong