Skip to content

はじめに

私たちは JavaScript の第3の時代 にいる。 今、主流のトレンドはパフォーマンス向上のために、パーサーやツールを Rust や Go で実装することである。

しかし、実際に JavaScript ツールを書くのは難しい。ましてや、それを Rust で書くとなるとさらに難易度が上がる。 私はこれらの技術を学ぶ過程で多くの苦労を経験したが、誰かが同じ苦しみを繰り返さないように願っている。

そのため、このガイドを執筆することでコミュニティに貢献したいと考えている。
そうすれば、あなたも私のように同じ苦難を経ることなく済むだろう。

現時点で Rust 側には少数の開発者しかいない。ぜひあなたもここにいて、私たちと共に参加してほしい。
そうすることで、誰もが楽しめるより良い、より速いツールを一緒に作り上げることができる。

概要

このガイドでは、標準的なコンパイラフロントエンドの段階を適用する:

ソーステキスト --> レキサ --> トークン --> パーサー --> AST

JavaScript パーサーを書くことはそれほど難しくない。
全体の10%がアーキテクチャ上の決定事項であり、残り90%は細部にわたる作業である。

アーキテクチャ上の決定事項は主に以下の2つのカテゴリに影響を与える:

  • パーサーのパフォーマンス
  • 生成された AST がどれだけ使いやすいか

Rust でパーサーを構築する前に、すべての選択肢とトレードオフを把握しておけば、
全体のプロセスがずっとスムーズになる。

パフォーマンス

パフォーマントな Rust プログラムの鍵は、メモリの割当を減らすことと、CPU サイクルの使用回数を減らすことだ。

メモリの割当がどこで行われているかは、VecBoxString などのヒープに割り当てられたオブジェクトを確認することで大体わかる。
それらの使用状況を評価することで、プログラムの速度の感覚を得られる。
割当が多ければ多いほど、プログラムは遅くなる。

Rust はゼロコスト抽象の力を与えてくれるため、抽象化がパフォーマンスを下げることをあまり心配する必要はない。
アルゴリズムの複雑さに注意を払いさえすれば、問題なく進められる。

INFO

The Rust Performance Book も併せて読むことをおすすめする。

Rust のソースコード

関数呼び出しのパフォーマンスが予測できない場合は、
「ソース」ボタンをクリックしてソースコードを読んでもらっても問題ない。
多くの場合、ソースコードは非常にわかりやすい。

INFO

Rust のソースコードをナビゲートする際、定義を探すには単に fn 関数名struct 構造体名enum 列挙型名 を検索すればよい。 これは Rust に一定の文法があることの利点の一つ(対比として JavaScript とは 😉)。