- Background: Last year read blog posts claiming bytecode interpreters are faster than tree-walking interpreters. Saw paper "AST vs. Bytecode: Interpreters in the Age of Meta-Compilation" shared by Stefan Marr. Decided to build two small interpreters in the same language and compare performance.
- The language: Chose to implement interpreters for parsing expression grammars (PEGs), not a general-purpose programming language. PEGs' expressions operate on hidden data structures and have rule applications like function calls. Used parser combinators instead of a custom syntax to define rules.
- Performance measurement: Ported ES5 grammar from Ohm to parser combinator style and used interpreters to parse jQuery, React, and Underscore source code. The tree-walking interpreter was about 2 - 3 times faster than the bytecode interpreter on V8 and JSC. Node (V8) results showed AST interp was 2.86x, 2.24x, and 2.04x faster for jQuery, React, and Underscore respectively. Bun (JSC) results showed AST interp was 3.69x, 3.2x, and 3.17x faster. But noted some caveats like difference between interpreting PEG and a real programming language and not optimizing interpreters much.
- Full source: Can find the full source of both interpreters on GitHub. Encouraged to provide suggestions for improvements. Thanks to David Albert and Kevin Lynagh for their help.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。