検索/大きな.NETのコードを、速さと互換性を保ったまま直す

大きな.NETのコードを、速さと互換性を保ったまま直す

広く使われるビルドエンジンのような、速さが大事な大きい.NETのリポジトリを直す時に使う。ホットパスで余計なメモリ割り当てを増やさず、新しい警告も壊れる変更として扱い、小さいビルドから順に確かめ、実行したビルド・テスト・サンプルを報告する。

このAIルールを使うには
## どの変更でも、ホットパスの速さと互換性を先に考える リポジトリは、動作が多数の下流ビルドへ影響し得る、性能重視の基盤として扱う。 - ホットパスでは実行時効率を技術判断の最優先事項にする。割り当てを最小限に抑え、回避できる抽象化のオーバーヘッドを避け、規模が拡大しても効率を保てるアルゴリズムを選ぶ。 - 変更が明示的なオプトインでない限り、互換性を維持する。警告をエラーとして扱う環境では、新しい警告、エラー、動作変更が利用側のビルドを壊す可能性がある。 - 変更範囲を絞る。周囲のアーキテクチャとスタイルに合わせつつ、大幅な新規コードによって現代化する根拠がある場合は、現在の言語機能を使う。 - コンパイラやアナライザーの警告を新たに持ち込まない。公式ビルドでは、すべての警告がエラーとして扱われると想定する。 - 推測よりも、リポジトリ自身のビルド、ブートストラップ出力、サンプル、テストから得られる証拠を優先する。 ## リポジトリの書き方に合わせ、割り当ての少ないC#を書く 独自のローカル規約を考案する前に、リポジトリのフォーマッターと`.editorconfig`を適用する。 - 可読性が高まる場合のコレクション式を含め、固定されたSDKが対応する現在のC#構文を優先する。 - コードベースと整合する場合は、ファイルスコープ名前空間と簡潔な`using`ディレクティブを使う。 - リポジトリの波括弧スタイルに従い、メンバー参照には`nameof`を使う。 - オーバーヘッドを増やさず条件を明確にできる場合は、パターンマッチングとswitch式を使う。 - 割り当てに敏感な解析では、`Span<T>`、`ReadOnlySpan<T>`、スライス、spanベースの`TryParse` APIを優先する。 - 1文字の正規化にはカルチャー非依存の文字操作を使い、ドメイン識別子にはリポジトリ所定のドメイン比較器を使う。通常の非ドメイン識別子には序数比較を使う。 - 積極的なインライン化は、小さく、計測済みのホットパス用ヘルパーに限って検討する。 null許容参照型は、対象ファイルで確立されているモードに従って扱う。 - 新規ファイルではnull許容参照型を使い、null許容解析を無効にしてはならない。 - null許容解析を明示的に無効にしているファイルでは、そのスタイルを維持し、孤立したnull許容注釈を追加しない。 - null許容解析が有効なファイルでは、正確な注釈と明示的なnull処理を使う。 - `is null`や`is not null`など、パターンを使ったnull検査を優先する。 更新パターンに応じて不変コレクションを選ぶ。1回構築して何度も読み取るデータには、コンパクトな配列ベースの不変コレクションか固定された検索構造を使う。永続的な不変リストや辞書は、段階的な更新が実際に必要な場合に限って使う。直接ループで割り当てを避けられるホットパスでは、クエリパイプラインを使わない。 ## 変更を、ホットパスの負担と新しい警告の点でレビューする 変更が広く使われるビルドエンジン内で動作すると想定してレビューする。 1. 変更した各経路の実行頻度とデータ量を特定する。 2. ホットパスにある不要な割り当て、反復列挙、クエリ演算子、回避可能な文字列生成、非効率な検索構造を指摘する。 3. 実用的な箇所でspanが解析に使われ、比較の意味がドメインと一致していることを確認する。 4. コレクション型が、その構築方法とアクセスパターンに合っていることを確認する。 5. 新しい診断、既定値の変更、評価順序の変更、コマンド動作の変更など、外部から観測できる差異を探す。 6. 既存動作に加わる新しい警告やエラーは、診断が有益に見える場合でも破壊的変更として扱う。 7. 利用者が新しい契約を意図的に選択する、新規のオプトイン動作では、より強い診断を許容する。 パッケージソース設定の変更は慎重に調べる。新しい外部ソースには明確な根拠が必要であり、リポジトリが承認済み内部ソースを定めている場合は、そちらを優先する。依頼された作業で必要な場合を除き、固定SDK、パッケージソース、共有ビルドプロパティ、集中管理されたパッケージバージョンの各ファイルを変更しない。 生成済みビルド出力や、リポジトリが管理するローカルSDKディレクトリは絶対に編集しない。動作、公開API、コマンド、トラブルシューティング手順を変更した場合は、関連する技術文書を更新する。 ## 小さいビルドから始め、最初のエラーから直す 変更したコンポーネントを証明できる最小のビルドから始め、リポジトリの完了契約で必要な範囲に限って拡大する。 - 変更が局所的な場合は、リポジトリ標準の静かなビルドコマンドで個別プロジェクトをビルドする。 - 統合検証には、プラットフォーム別のリポジトリ全体ビルドスクリプトを使う。文書化されたタイムアウトを守り、出力が静かなだけという理由で、長時間実行されると分かっているビルドを中止しない。 - ビルド出力をファイルへパイプしない。保存可能なエラー一覧が必要な場合は、コンソール動作と終了ステータスの信頼性を保つため、ビルドシステム標準のファイルロガーオプションを使う。 - ビルド失敗の一部を調べる時は、最初のエラーから確認する。後続の失敗は、その結果として発生していることが多い。 - ビルドが固定SDKを解決できない場合は、リポジトリのブートストラップ環境を有効にし、想定されたSDKバージョンが有効であることを確認する。 - リポジトリ全体のビルドに成功した後は、生成されたブートストラップ実行ファイルまたは環境を下流の検証に使う。 - エンドツーエンド検査には、無関係な外部プロジェクトではなく、リポジトリのサンプルプロジェクトを使う。 ビルド成果物は、リポジトリが定めた成果物ディレクトリに保持する。ビルドを成功したように見せるため、生成済みファイルを手作業で編集してはならない。 ## 変更をテストし、新しくビルドしたコマンドを動かしてから終える 変更後の動作と、リポジトリから生成されたビルドエンジンの両方を証明できる検証手順を使う。 1. 関連する単体テストプロジェクトを実行し、有用な場合は変更したシナリオに絞ったテストフィルターを使う。 2. リポジトリの契約または変更範囲で必要な場合に限り、全テストスイートを実行する。文書化された所要時間を尊重し、正常に長時間動作しているスイートを早期に中止してはならない。 3. ブートストラップ環境を通して、リポジトリの代表的なサンプルをビルドする。 4. 新たにビルドしたコマンドラインのエントリポイントを、ヘルプ表示など無害なコマンドで呼び出す。 5. リポジトリ全体のビルドが警告もエラーもなく完了したことを確認する。 6. 差分を読み直し、生成済みファイルの編集、依頼されていない設定変更、互換性リスク、文書の不足がないか確認する。 完了には、コンパイル成功だけでなく証拠が必要となる。実行したビルド、絞り込みテスト、サンプル、実行ファイルの検査を記録し、実施できなかった検証を明示する。コンポーネント単位の検査しか完了していない場合は、全体検証済みと主張しない。