**WAT パーサーの性能向上**

2026/01/15 16:49

**WAT パーサーの性能向上**

RSS: https://news.ycombinator.com/rss

要約

日本語訳:

改善された概要

wasm-language-tools
ライブラリは、WAT パーサの完全な書き直しにより v0.5 で大幅な性能向上を実現しました。複雑な WebAssembly Text Format スニペットでベンチマークを行った結果、旧パーサは約 59 µs を要したのに対し、新実装では約 13 µs で完了します。これは約 350 % の改善であり、統計的に有意な差であって偶然によるものではありません。

主な技術的変更点

  1. レキサの最適化

    • よく使われる括弧やキーワードは
      LazyLock
      に格納された既知の緑色トークン/ノードとして事前にクローンされ、再度割り当てを行わないようにします。
    • キーワード認識はバイトレベルでプレフィックスマッチング(
      self.input.as_bytes().starts_with(keyword.as_bytes())
      )を使用し、その後次の文字が識別子文字でないか確認することで「function」のような偽陽性を防止します。
    • 文字列とコメント以外のトークンは
      get_unchecked
      を用いて UTF‑8 境界チェックをスキップして生成されます。
  2. カスタムトークン型 – レキサは直接

    rowan::GreenToken
    を作成する代わりに、軽量な
    Token<'s>
    kind: SyntaxKind
    ,
    text: &'s str
    )を発行します。

  3. パーシング戦略 – パース中に子トークン/ノードを保持するための単一共有

    Vec
    を使用し、必要に応じてそれを消費して
    rowan::GreenNode
    を生成します。スタック型の開始インデックス(
    usize
    )で範囲を追跡します。
    これにより、多くの一時的ベクタや不要な
    unwrap
    呼び出しが発生していた以前の
    rowan::GreenNodeBuilder
    アプローチを回避できます。

この書き直しは、従来の

winnow
パーサ―コンビネータライブラリを手作りのレキサ/パーサに置き換え、多数のメモリアロケーションとチェックを排除しました。高速化されたパーサは v0.5 以降のデフォルトエンジンとして採用される予定で、
wasm-language-tools
をベースにしたすべてのツールがより効率的に動作します。大量の WAT を生成・操作する開発者や企業にとって、この改善はビルド時間の顕著な短縮、IDE とのインタラクションのスムーズ化、および開発・デプロイ時のリソース使用量の削減へ直結します。

本文

元の WAT パーサは遅かった
wasm-language-tools v0.5 以前における WAT(WebAssembly Text Format)パーサは、性能期待を満たせず遅延していました。完全に書き直した結果、ベンチマークで 350 % の向上が確認されました。


パーサの最適化手法

  • ハンドメイドのパーサを書く
    従来は

    winnow
    (コンビネータライブラリ)を使用していました。便利ですが、一般的にコンビネータは命令型パーサより遅くなります。自作パーサなら速度が速く、さらに最適化しやすいです。

  • よく使われる緑色トークンとノードをクローン
    WAT は括弧やキーワードが多いため、それらを毎回生成するとコストがかさみます。

    rowan::GreenToken
    /
    GreenNode
    は内部で
    Arc
    を保持しています。よく使われるトークン・ノードを事前に作成し、
    LazyLock
    に格納しておけば、必要時にクローンするだけで済みます。

  • キーワードマッチング
    単語を先に字句解析した後にリストと比較するのではなく、ソース文字列の接頭辞を直接チェックします。

    self.input.as_bytes().starts_with(keyword.as_bytes())
    

    function
    func
    で始まる」などの誤検知を防ぐために、次の文字が識別子文字でないことも確認します。

  • ASCII トークンには

    get_unchecked
    を使用
    文字列やコメント以外は純粋な ASCII です。
    str::get_unchecked
    を使うと、
    String::from_utf8
    が行う不要な UTF‑8 境界チェックを省けます。

  • 軽量

    Token
    型を自前で定義
    ライザは
    Token<'s>
    (完全な
    rowan::GreenToken
    の代わり)を発行します。これにより割当オーバーヘッドが削減されます。

    struct Token<'s> {
        kind: SyntaxKind,
        text: &'s str,
    }
    

    impl From<Token<'_>> for rowan::NodeOrToken<rowan::GreenNode, rowan::GreenToken>
    を実装すれば、構文木を作る際に変換が容易になります。

  • ノードごとの Vec 割当を回避
    構文木には多くのノードがあります。各ノードで新しい

    Vec
    を割り当てると頻繁な割当・解放が発生します。
    rowan::GreenNodeBuilder
    に触発され、単一の共有
    Vec
    を保持します。

    • パース中は子トークン/ノードをこのベクタに push。
    • ノード完了時には、記録した開始インデックスから現在長さまでをスライスとして取り出し、
      GreenNode
      のコンストラクタへ渡します。
      この手法はスタックのように機能しますが、明示的なスタック構造を排除できます。
  • 結果
    最終的に作成したパーサは、以前よりもシンプルかつ高速です。以下はベンチマークで使用されたコードスニペットです。

(module
    (func $f1 (param $p1 i32) (param $p2 i32) (result i32)
        (i32.add (local.get $p1) (local.get $p2))
    )
    (global $g1 f64 (f64.const 0))
    (func $f2 (result f64)
        (global.get $g1)
    )
    (type $t (func (result f64)))
    (func $f3 (type $t)
        (call $f2)
    )
    (func (export "f32.min_positive") (result i32) (i32.reinterpret_f32 (f32.const 0x1p-149)))
    (func (export "f32.min_normal") (result i32) (i32.reinterpret_f32 (f32.const 0x1p-126)))

    (rec (type $r (sub $t (struct (field (ref $r))))))
    (global (;7;) (mut f32) (f32.const -13))
    (rec
        (type $t1 (sub (func (param i32 (ref $t3)))))
        (type $t2 (sub $t1 (func (param i32 (ref $t2)))))
    )
    (global (;8;) (mut f64) (f64.const -14))

    (func (export "f32.max_finite") (result i32) (i32.reinterpret_f32 (f32.const 0x1.fffffep+127)))
    (func (export "f32.max_subnormal") (result i32) (i32.reinterpret_f32 (f32.const 0x1.fffffcp-127)))
)

最適化後のベンチマーク結果は以下の通りです。

パーサ時間(µs)
old59.473 – 59.648
new13.004 – 13.299

新しいパーサは旧バージョンを一貫して上回り、約350 % の速度向上を達成しています。

同じ日のほかのニュース

一覧に戻る →

2026/01/21 3:16

**2019年 「見えないままに隠された26000年前の天文モニュメント」**

## Japanese Translation: **概要:** フーバーダムの西側にあるモニュメント・プラザは、地球の25,772年周期の軸進動をタレーズ床にマッピングした芸術的な敬意表現です。設計の中心には旗竿があり、これは進動円の中心として機能します。その周囲には巨大な翼付きブロンズ像が配置されています。床はダム開業時(1936年)のポラリス、ピラミッド建設中のトゥバン、そして将来の北極星としてプロジェクトされたベガを示しており、技術図面には惑星位置が正確に配置されているため、1日単位での日付計算が可能です。1931年に米国再利用局(U.S. Bureau of Reclamation)から委託され、1936年に完成したモニュメントは後にモニュメント・プラザと名付けられました。アーティストのオスカー J. W. ハンセン氏の意図表明は抽象的であり、歴史家エメー・ウッドワードが提供したアーカイブ写真には「セーフティアイランド」という早期建設名が示されています。デザインはロング・ナウ(Long Now)の10,000年時計コンセプトを反映しており、天体周期の公衆展示に類似するものとしてインスピレーションを与える可能性があります。米国再利用局が計画図をInternet Archiveへ公開したことは、ダム文書へのオープンアクセス化の動向を示しています。訪問者には短い音声解説のみが提供されるため、詳細な科学内容はほぼ隠蔽されており、教育的広報は限定的です。それでもプラザは20世紀初頭の大規模インフラプロジェクトにおける芸術と科学の統合を示す具体例として、歴史家・天文学者・エンジニアに貴重な実証を提供します。

2026/01/21 6:34

**日本のスナックバーの秘密世界へようこそ** 「おかかん」と呼ばれることもある日本のスナックバーは、地元ならではの味と創造性を堪能できる隠れた宝石です。小さな飲食店が揃うこれらのお店では、フライドライスボール(おにぎり)や塩気のあるペストリー、甘いスイーツなど、手軽で美味しい一口料理を提供しつつ、親切なサービスも楽しめます。 - **雰囲気**:街角の居心地の良い隅っこや静かな路地裏が主流です。 - **メニューの見どころ**: - 海苔と醤油をトッピングしたフライドライスボール - 蜂蜜でコーティングされた甘いかぼちゃロール - 豚肉と竹笹の餡が入った塩味の餃子 - **特徴**: - 多くのお店では、新鮮な地元産食材を使用しています。 - 季節ごとにメニューが変わるローテーションもあります。 おかかんへ足を踏み入れることは、単なるスナックの取得以上の体験です。便利さと伝統が交差する日本の食文化を垣間見る瞬間なのです。

## Japanese Translation: スナックバー―第二次世界大戦後に厳しい酒類法を回避するために登場した、女性が経営する小規模カフェ―は、日本独自の社会的ハブとして確立しました。全国には約10万店舗が存在し、コンビニエンスストアの数を2倍以上上回ります。これらは「ママさん」と呼ばれる年配女性によって運営され、家庭的な雰囲気でシンプルなお菓子や飲み物を提供します。主目的は食べ物や飲み物だけでなく、会話と個人的つながりを得られる居心地の良い空間を提供することです。 このコンセプトは日本の戦後経済成長期に急速に広がりました。1960年代後半には全国的にスナックバーが普及し、コミュニティのハブとなり、その後1980年代中頃から1990年代初頭まで存続しました。特徴として「ボトルキープ」システムがあります:常連客は自分のウイスキーや焼酎をラベル付けして保管し、次回訪問時に利用できます。伊良谷真由子(Mayuko Igarashi)氏などの研究者は2021年以降、1200件以上の店舗を巡り、旅行者とこれまで地元住民限定だった場所を結びつけています。 スナックバーはCOVID-19以前から人気低下やホスト人口の高齢化、カラオケバーやチェーン居酒屋との競争など課題に直面していますが、新しいトレンドが存続を支えています。アニメテーマのスナック、SNSプロモーション、LGBTQ+来客へのより包括的な対応などです。著名例として新橋の「Aeru」のウララ氏は14年間でタロットリーディングと現代のマッチメイキング手法を用いて90組以上のカップルを紹介しています。 デジタルライフの圧力にもかかわらず、スナックバーはママさんとの真の人間関係や親密な会話が評価され続けています。旅行者は、豪華ホテルや寿司教室など高価な観光活動よりも、これらの場所での思い出深い体験を重視しており、地元経済と伝統的ホスピタリティ慣行の保存に対する継続的な関連性を示しています。

2026/01/21 1:48

**UNIXパイプ・カードゲーム**

## Japanese Translation: 記事は、子どもに Unix パイプコマンドチェーンの構築方法を教えるカードベースのボードゲームについて説明しています。デッキには、`cat`、`grep`、`tail`、**`head`、`wc`、`sort`、`uniq`** などの主要な Unix コマンドを表すカードと、特定行の表示、出現回数のカウント、非表示コマンドチェーンの作成といったタスクが含まれています。ローカルの Unix システムが利用できない場合は、ブラウザベースの jslinux を使用できます。 ゲームプレイは時計回りに進行します:プレイヤーはカードを引き、最短または最長の有効パイプラインを目指すかどうかを選択し、タスクを完了した最初のプレイヤーがポイントを獲得します。例として、最も頻出する行を見つけるチェーンを示すラウンドがあります: ``` cat 03.txt | sort | uniq -c | sort -n | tail -1 ``` ゲームは €5,00 EUR(現在完売)で販売されており、印刷可能な PDF(`unix-pipe-cards.pdf`、`unix-pipe-box.pdf`)も入手できます。 GitHub 上のソースコードリポジトリ(`github.com/jackdoe`)、共著者 Jackie、連絡メールアドレス (`b0000@fastmail.com`) と CC BY 4.0 ライセンスが製品に付属しています。 「UNIX Pipe Game – Process Substitution」という拡張パックでは、プロセス置換用のコマンド(`paste`、`tr`、`cut`、`bc`)を追加します。 著者は Python の基礎、C ポインタ、機械語、ランレングス符号化、関数合成、RISCV アセンブラなどをカバーする追加のカードゲームも公開しており、子ども向けにプログラミング概念をゲーミフィケーションする広範な取り組みを示しています。