10 ポイント 投稿者 GN⁺ 2025-08-05 | まだコメントはありません。 | WhatsAppで共有
  • V8エンジンで JSON.stringify 関数の性能を2倍以上高め、データ直列化の速度改善を実現
  • 副作用のないオブジェクト 向けの最適化経路を導入し、多数の防御的なチェックロジックを省略することで、一般的なデータオブジェクトで大きな高速化を達成
  • 文字列処理 では1バイト/2バイトの区別、SIMDの活用、一時バッファ構造の変更など、ハードウェアとメモリの両面で高度な手法を適用
  • 数値変換プロセス では従来のGrisu3アルゴリズムをDragonboxに置き換え、Number.toString() 呼び出し全体でも高速な変換を実現
  • 一部の引数や形式では通常の直列化経路に戻るが、ほとんどのWeb開発の場面 では自動的に最適化の恩恵を受けられる

概要

  • JSON.stringifyJavaScriptでデータを文字列に変換 する中核関数
  • この関数の性能向上は、ネットワークリクエストやlocalStorageへの保存など、Web上の非常に重要な処理にも好影響を与える
  • 最新のV8エンジニアリングにより、この機能の速度は 2倍以上改善 されており、主要な最適化手法を詳しく紹介する

副作用のないFast Path経路

  • 最適化の核心は、副作用(side-effect)のない状況 でのみ利用できる 高速な直列化経路 の適用
  • このような状況では、再帰ではなく 反復的(iterative)な構造 でオブジェクトを走査することで、スタックオーバーフロー検査が不要になり、より深いオブジェクトの直列化も試みられる
  • データオブジェクトが単純な場合、V8は遅い通常ロジックの代わりにこのFast Pathを利用し、多くのチェックを省略して高速化する

多様な文字列表現の処理

  • V8は 1バイト/2バイト文字(ASCII/非ASCII) に応じて文字列を異なる形で保存し、1つでも非ASCIIがあると全体を2バイトとして扱う
  • 文字列直列化の性能向上のため、文字列タイプごとに別個のアルゴリズム版 を作成してコンパイルしている
  • 処理中に文字列インスタンスの型を確認する必要があるため、2バイト文字列が検出されると、適切な2バイト直列化器が状態を引き継ぐ
  • その結果、文字列エンコーディングごとの経路切り替え負荷は事実上ない
  • 結果は1バイト、2バイトのバッファをそれぞれ作成し、最後に単純に結合する

SIMDによる文字列直列化の最適化

  • JavaScriptの文字列には、JSON直列化時にエスケープが必要な文字が含まれることがある
  • 長い文字列は SIMDハードウェア命令 (ARM64 Neonなど) で複数バイトを一度に検査する
  • 短い文字列は SWAR方式 により、汎用レジスタ上のビット演算で複数文字を同時に処理する
  • いずれの方式でも、ほとんどの場合は特別な変換なしに文字列全体を高速にコピーできる

Express Lane(超高速経路)の追加

  • Fast Path内でも、プロパティ検査などの反復作業なしにキーのコピーだけで直列化 できるよう、Express Laneを用意
  • オブジェクトの hidden classフラグ を活用し、キーにSymbolがなく、すべてenumerableで、エスケープ不要のまま直列化できる場合は 'fast-json-iterable' としてマークする
  • 同じhidden classを持つ別のオブジェクトを直列化する際は、追加の検査なしに すぐキーのコピーを実行 する
  • この手法は JSON.parse でも高速なキー比較に応用されている

より高速なdouble-to-stringアルゴリズム

  • 数値を文字列に変換する処理も頻度が高く、複雑さを伴う
  • 従来のGrisu3アルゴリズムをDragonboxに置き換え ることで、Number.prototype.toString() の呼び出し全体でも性能向上が得られる

一時バッファ構造の最適化

  • 文字列構築時、従来は 単一の連続バッファ を使っていたため、空きが足りなくなるたびに全体コピーが発生するオーバーヘッドがあった
  • 新しい方法では 分割(segmented)バッファ構造 を採用し、複数の小規模バッファを必要に応じて連結する
  • これにより空き不足時も、全体コピーなしで新しいバッファを割り当てるだけ で済む

制限事項

  • Fast Pathは単純なデータ直列化に限って動作する
  • 以下の条件に合致しない場合は通常経路を使用する
    • replacer または space 引数は使用不可(Pretty-Printや変形は不可)
    • toJSON カスタムメソッドを持たない単純なオブジェクトである必要がある
    • インデックスベースのプロパティ があると低速経路へ移行する
    • ConsStringなどの特殊文字列 は処理しない
  • ほとんどのデータ直列化、APIレスポンス生成、設定キャッシュなど一般的な用途では、自動的に最適化の効果が適用される

結論

  • JSON.stringify基本設計からメモリ処理、文字処理まで 全領域でアプローチを再構成し、JetStream2ベンチマーク基準で 2倍以上の高速化 を達成
  • この改善は V8バージョン13.8(Chrome 138)以降 でそのまま体験できる

まだコメントはありません。

まだコメントはありません。