Use `Range#cover?` for `this_week?`/`this_month?`/`this_year?`

rails/rails

this_week?this_month?this_year? が内部で Range#include? を使っていたため、日付範囲を走査するコストが高くなっていました。この PR では Range#cover? に置き換えることで、同等の判定結果を保ちつつ実行速度を大幅に向上させます。

背景

これらのメソッドは現在日の属する週・月・年を判定する際に、Date.current.all_week などが返す Date 範囲 に対して include? を呼び出していました。include? は範囲の各要素を #succ で順に走査するため、this_year? では約 365 回の比較が毎回発生します。

実際に this_year? が 365 回のイテレーションを行うことは、頻繁に呼び出される日時判定において非効率です。パフォーマンス改善のためには、範囲の端点だけを比較すればよいケースであることが判明しました。

同様の問題は this_quarter? でも指摘され、PR #57963 で既に Range#cover? が導入されています。本変更はその成果を this_week?this_month?this_year? にも適用し、メソッド群を一貫させることを目的としています。

技術的な変更

activesupport/lib/active_support/core_ext/date_and_time/calculations.rb において、4 つのメソッドが include? から cover? へ置き換えられました。変更は次の通りです。

変更前:

def this_week?(start_day = Date.beginning_of_week)
  ::Date.current.all_week(start_day).include?(to_date)
end

def this_month?
  ::Date.current.all_month.include?(to_date)
end

def this_year?
  ::Date.current.all_year.include?(to_date)
end

変更後:

def this_week?(start_day = Date.beginning_of_week)
  ::Date.current.all_week(start_day).cover?(to_date)
end

def this_month?
  ::Date.current.all_month.cover?(to_date)
end

def this_year?
  ::Date.current.all_year.cover?(to_date)
end

all_weekall_monthall_year が返す Date 範囲 は端点だけで包含判定可能です。cover? はその端点比較のみを行うため、走査コストが不要となり、実行速度が 10〜100 倍向上すると報告されています。機能的な振る舞いは変わらず、同一の真偽値が返ります。

設計判断

この変更は Range#cover? という既存メソッドの活用を選択した点が特徴です。新たな API を追加することなく、既存のメソッドシグネチャを保ちつつ内部実装を最適化しています。

this_quarter? がすでに cover? を使用していたことから、一貫性の確保 が設計上の主要な判断材料となりました。コード量の増加を抑え、後方互換性を維持しながらパフォーマンス改善を実現しています。

まとめ

this_week?this_month?this_year?Range#include? から Range#cover? に置き換わり、走査コストが排除されました。挙動はそのままで、呼び出し頻度が高い日時判定に対して大幅な速度向上が期待できます。これにより、同系列メソッド全体が 端点比較ベース に統一され、Rails コアの一貫性と性能が同時に改善されました。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
1c100404

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

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文、背景、技術的変更、設計判断(任意)およびまとめがすべて揃っており、総論→各論→結論の流れが明確です。

カスタムMarkdown構文 ⚠ WARNING

シンタックスハイライト・GitHubリンク記法の正確性

コードブロックのファイル名付きハイライトは正しい形式です。PR リンクは `[PR #57997](URL)` となっており、推奨の `[ #57997 ](URL)` 形式と完全には一致していません。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

Rails の内部実装やパフォーマンス改善に関する記述で、専門知識を持つエンジニア向けの内容となっています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論・各論・結論の構成になっており、段落はトピックセンテンスで始まり一段落一トピック、長さも適切です。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事中の before/after コードブロックは提供された Diff と正確に一致しており、変更点が正しく反映されています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

Range#include?、Range#cover?、Date 範囲 など、PR で使用されている用語が正確に使われています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

パフォーマンス向上が 10〜100 倍という主張は PR の記述と合致しており、技術的説明に誤りはありません。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

全ての主張が PR タイトル、説明、Diff で裏付けられており、捏造や推測は見られません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR 番号 #57997、#57963、10〜100 倍という数値表記が正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトルは PR タイトルと完全に一致しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事内に PR で言及されていない外部知識(LTS、リリース日程等)は含まれていません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「既に」導入されたことなど、時間表現は PR の記述と一致しています。