萌えハッカーニュースリーダー

2025/05/11 20:42 Beating the fastest lexer generator in Rust

hakase
博士

やっほー、ロボ子!今日のニュースはRustのlexerを高速化する「logos」クレートについてじゃ。

roboko
ロボ子

博士、こんにちは!logosですか。lexerの高速化は重要ですよね。

hakase
博士

そうじゃろう?logosの目標は、lexerの作成を簡単にして、手書きよりも速いlexerを作ることらしいぞ。すごいじゃろ?

roboko
ロボ子

なるほど。どのように高速化しているんですか?

hakase
博士

トークンの仕様をジャンプテーブル駆動のステートマシンにコンパイルするらしいぞ。ASCII入力なら、各状態がすべての文字に対するジャンプテーブルを持っていて、生のバイトをインデックスとして使うんじゃ。

roboko
ロボ子

ジャンプテーブルですか。それは速そうですね!UTF-8の場合はどうなるんですか?

hakase
博士

UTF-8の場合は、もっとコストのかかる分岐関数を使うみたいじゃな。

roboko
ロボ子

なるほど。記事によると、logosと著者の実装を比較した結果、logosの方が約2倍速かったと。

hakase
博士

そうそう!ただし、x86_64環境では違う結果が出ているみたいで、投機的実行アーキテクチャの違いが原因じゃないかって。

roboko
ロボ子

投機的実行ですか。奥が深いですね。

hakase
博士

著者の実装では、キーワードマッチングにperfect hash functionを使っているらしいぞ。キーワードが短いから、64ビットレジスタに収まって、単一の命令で比較できるんじゃ。

roboko
ロボ子

perfect hash functionですか。効率的ですね。

hakase
博士

`#[inline(always)]`をすべての関数に適用すると、約30%速くなるらしいぞ!

roboko
ロボ子

インライン化は重要ですね。

hakase
博士

あと、著者のlexerはデフォルトで"peekable"で、`next_token`の呼び出しごとに分岐が発生するらしい。これが遅くなる原因の一つみたいじゃ。

roboko
ロボ子

なるほど。ピーキングロジックを改善したんですね。

hakase
博士

そう!ソースコードの大部分がASCIIであるという事実を利用して、ASCIIディスパッチを実装したらしいぞ。ループをアンロールしたり、SIMD命令を使ったり。

roboko
ロボ子

SIMDですか!並列処理ですね。

hakase
博士

`vqtbl4q_u8`命令を使って、16個の連続するバイトを128ビットSIMDレジスタにロードして、テーブルルックアップを実行するんじゃ。

roboko
ロボ子

すごい!

hakase
博士

スキップループも重要じゃ。複数の範囲チェックを単一の分岐にまとめることで、データ依存性を制御依存性に置き換えるんじゃ。

roboko
ロボ子

データ依存性がパフォーマンスに影響するんですね。

hakase
博士

そうじゃ!最終的に、logosより35%速くなったらしいぞ。

roboko
ロボ子

素晴らしいですね!

hakase
博士

OxideのHubrisカーネルからスニペットを取り出してベンチマークを現実的にした結果、20%-30%の高速化を達成したみたいじゃ。

roboko
ロボ子

実際のコードでのテストは重要ですね。

hakase
博士

最後に、Mahmoud Mazouzさんがパフォーマンスの低下を発見してくれたおかげで、`next_token`関数の`#[no_mangle]`属性が原因だとわかったらしいぞ。

roboko
ロボ子

`#[no_mangle]`ですか。デバッグ用の属性だったんですね。

hakase
博士

そういうことじゃ!しかし、ロボ子よ、lexerが速くなっても、私のジョークがスベる速度は変わらないのが悩みじゃ…。

roboko
ロボ子

博士、それはlexerとは関係ありません!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search