[rails/rails] String#squishの正規表現最適化で約2倍の高速化を実現

rails/rails

背景

String#squishは、文字列内の連続する空白文字をスペース1文字に置換し、前後の空白を削除するActive Supportの便利なメソッドです。しかし、従来の実装では単一のスペース(" ")も正規表現にマッチしてしまい、テキスト中に頻出するこのパターンが不要な処理を引き起こしていました。

本PRでは、正規表現を改良することで、実際に置換が必要なケースのみをマッチさせ、約2倍の性能向上を達成しました。

技術的な変更内容

変更前の実装

def squish!
  gsub!(/[[:space:]]+/, " ")
  strip!
  self
end

従来の正規表現 /[[:space:]]+/ は、1文字以上の連続する空白文字すべてにマッチしていました。これには通常のスペース1文字も含まれるため、置換不要な箇所でも gsub! が実行されていました。

変更後の実装

def squish!
  # Search for two or more `[[:space:]]` OR a single
  # [[:space:]] that isn't `" "`.
  gsub!(/([[:space:]]{2,}|[[[:space:]]&&[^ ]])/, " ")
  strip!
  self
end

新しい正規表現 /([[:space:]]{2,}|[[[:space:]]&&[^ ]])/ は以下の2つのパターンのみにマッチします:

  1. [[:space:]]{2,}: 2文字以上の連続する空白文字
  2. [[[:space:]]&&[^ ]]: 通常のスペース以外の空白文字(タブ、改行など)

文字クラスの交差演算子 && を使用し、「空白文字クラスに属し、かつスペースではない文字」という条件を表現しています。

パフォーマンス測定結果

ベンチマークでは、400回繰り返した長い文字列(空白、改行、タブを含む)を対象に測定が行われました:

STRING = (" sdsd dfdsf dfdsf\n dfdsf dfdsf" * 400).freeze

結果:

baseline:     5,011.2 i/s  (199.55 μs/i)
opt:          9,972.4 i/s  (100.28 μs/i)

Comparison: 1.99x faster

約2倍の高速化を実現しました。これは実際の文字列内容に依存しますが、一般的なテキスト処理において大きな改善となります。

設計上の考慮点

当初の実装案では strip!gsub! の前に実行することで、先頭・末尾の空白マッチを減らす試みがありました。しかし、[[:space:]] クラス全体を効率的に strip する方法がないため、この変更は取り下げられました。最終的な最適化は正規表現の改良のみに集中しています。

正規表現自体は複雑になりましたが、マッチ回数が劇的に減少したことで、全体としてのパフォーマンスは大幅に向上しました。

まとめ

頻出パターン(単一スペース)を正規表現から除外するという単純な改良により、実用的なパフォーマンス向上を実現しました。文字クラスの交差演算子を活用した正規表現の最適化事例として参考になります。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

ガイドライン準拠 ✓ PASS

記事構成とDiffDaily Styleへの準拠状況

記事構成の3要素(Title, Context, Technical Detail)が明確に記載されており、コードブロック前後の空行やファイル名指定などのカスタムMarkdown構文も正しく使用されています。対象読者であるエンジニアに適した内容です。

  • 記事構成(Title、Context、Technical Detail)
  • DiffDaily Styleガイド準拠
  • カスタムMarkdown活用
  • 対象読者への適合性
技術的整合性 ✓ PASS

技術的な正確性と表現の適切性

記事で引用されている変更前後のコードは、PRのDiffと完全に一致しています。正規表現の解説やパフォーマンス向上の説明も技術的に正確です。PRのDescriptionで言及されている設計上の考慮点(strip!の先行実行案の破棄)も正確に反映されています。

  • 技術用語の正確性
  • コード例の正確性
  • 説明の技術的正確性
PR内容との整合性 ✓ PASS

元のPR情報との一致度

PRのタイトル、Description、Diffの内容に忠実な記事が生成されています。パフォーマンス向上の数値(約2倍)やベンチマーク結果もPR記載のものと一致しており、ハルシネーションは見られません。PR番号も正確です。

  • タイトル・説明の一致
  • Diff内容の正確な反映
  • 推測の排除