검색/큰 .NET 코드베이스를 빠르고 호환되게 유지하며 고치기

큰 .NET 코드베이스를 빠르고 호환되게 유지하며 고치기

널리 쓰이는 빌드 엔진처럼 성능이 중요한 큰 .NET 저장소를 고칠 때 사용합니다. 핵심 실행 경로에서 불필요한 메모리 할당을 늘리지 않고, 새 경고도 호환성을 깨는 변경으로 다루며, 가장 작은 프로젝트부터 빌드하고, 실행한 빌드·테스트·샘플을 알려 줍니다.

이 AI 규칙을 사용하려면
## 모든 변경에서 핵심 경로의 속도와 호환성을 먼저 생각하기 저장소를 동작이 많은 하위 빌드에 영향을 줄 수 있는 성능 핵심 인프라로 다룬다. - 핵심 실행 경로에서는 런타임 효율을 엔지니어링의 최우선 순위로 삼는다. 메모리 할당을 최소화하고, 피할 수 있는 추상화 오버헤드를 없애며, 규모가 커져도 효율을 유지하는 알고리즘을 선택한다. - 변경 사항이 명시적인 선택 적용 방식이 아니라면 호환성을 유지한다. 경고를 오류로 처리하는 환경에서는 새 경고, 오류 또는 동작 변경이 사용자의 빌드를 중단시킬 수 있다. - 변경 범위를 집중시킨다. 주변 아키텍처와 스타일을 따르되, 상당한 양의 새 코드가 현대화를 정당화할 때는 현재 언어 기능을 사용한다. - 컴파일러나 분석기 경고를 새로 도입하지 않는다. 공식 빌드는 모든 경고를 오류로 처리한다고 가정한다. - 추측보다 저장소 자체의 빌드, 부트스트랩 출력, 예제, 테스트에서 얻은 증거를 우선한다. ## 저장소 스타일에 맞춰 파싱할 때 할당이 적은 C# 쓰기 독자적인 로컬 스타일 규칙을 만들기 전에 저장소의 포매터와 `.editorconfig`를 적용한다. - 명확성을 높일 수 있는 컬렉션 식을 포함해 고정된 SDK가 지원하는 현재 C# 문법을 우선한다. - 코드베이스와 일치하는 경우 파일 범위 namespace와 간결한 `using` 지시문을 사용한다. - 저장소의 중괄호 스타일을 따르고 멤버를 참조할 때 `nameof`를 사용한다. - 오버헤드를 추가하지 않고 조건을 더 명확하게 만들 수 있다면 패턴 매칭과 switch 식을 사용한다. - 메모리 할당에 민감한 구문 분석에서는 `Span<T>`, `ReadOnlySpan<T>`, 슬라이싱, span 기반 `TryParse` API를 우선한다. - 단일 문자 정규화에는 문화권 비종속 문자 연산을 사용하고, 도메인 식별자에는 저장소가 지정한 도메인 비교기를 사용한다. 일반적인 비도메인 식별자에는 서수 비교를 사용한다. - 공격적인 인라인화는 크기가 작고 측정된 핵심 실행 경로의 보조 함수에만 고려한다. nullable 참조 형식은 파일에서 정한 모드에 따라 처리한다. - 새 파일은 nullable 참조 형식을 사용하며 nullable 분석을 비활성화해서는 안 된다. - nullable 분석을 명시적으로 비활성화한 파일은 해당 스타일을 유지하고, 고립된 nullable 주석을 추가하지 않는다. - nullable 분석이 활성화된 파일은 정확한 주석과 명시적인 null 처리를 사용한다. - `is null`과 `is not null` 같은 패턴 기반 null 검사를 우선한다. 업데이트 패턴에 따라 변경 불가능한 컬렉션을 선택한다. 한 번 구성하고 여러 번 읽는 데이터에는 배열 기반의 간결한 변경 불가능 컬렉션이나 고정된 조회 구조를 사용한다. 점진적 업데이트가 실제 요구 사항일 때만 영속적인 변경 불가능 목록이나 사전을 사용한다. 직접 반복문으로 메모리 할당을 피할 수 있는 핵심 실행 경로에서는 쿼리 파이프라인을 사용하지 않는다. ## 핵심 경로의 비용과 새 경고를 기준으로 변경 검토하기 변경 사항이 널리 사용되는 빌드 엔진 내부에서 실행된다고 가정하고 검토한다. 1. 변경된 각 경로의 실행 빈도와 데이터 양을 파악한다. 2. 핵심 실행 경로의 불필요한 메모리 할당, 반복 열거, 쿼리 연산자, 피할 수 있는 문자열 생성, 비효율적인 조회 구조를 지적한다. 3. 실용적인 위치에서 구문 분석이 span을 사용하는지, 비교 의미가 도메인과 일치하는지 확인한다. 4. 컬렉션 형식이 구성 및 접근 패턴에 맞는지 확인한다. 5. 새 진단, 변경된 기본값, 재정렬된 평가 순서, 달라진 명령 동작 또는 외부에서 관찰할 수 있는 다른 차이를 찾는다. 6. 진단이 유용해 보이더라도 기존 동작에 추가되는 새 경고나 오류는 호환성을 깨는 변경으로 다룬다. 7. 사용자가 새 계약을 의도적으로 선택하는 새로운 선택 적용 동작에서는 더 엄격한 진단을 허용한다. 패키지 소스 구성 변경을 주의 깊게 검토한다. 새로운 외부 소스에는 명시적인 근거가 필요하며, 저장소가 승인된 내부 소스를 정의한 경우 이를 우선한다. 요청된 작업에 필요하지 않다면 고정 SDK, 패키지 소스, 공유 빌드 속성 또는 중앙 관리 패키지 버전 파일을 변경하지 않는다. 생성된 빌드 출력이나 저장소가 관리하는 로컬 SDK 디렉터리를 절대 편집하지 않는다. 동작, 공개 API, 명령 또는 문제 해결 지침이 변경되면 관련 기술 문서를 업데이트한다. ## 가장 작은 프로젝트부터 빌드하고 가장 먼저 난 오류부터 고치기 변경된 구성 요소를 입증할 수 있는 가장 작은 빌드부터 시작하고, 저장소의 완료 계약이 요구하는 범위까지만 확장한다. - 변경이 국소적이면 저장소의 표준 조용한 빌드 명령으로 개별 프로젝트를 빌드한다. - 통합 검증에는 플랫폼별 전체 저장소 빌드 스크립트를 사용한다. 문서화된 시간 제한을 지키며, 출력이 조용하다는 이유만으로 오래 걸린다고 알려진 빌드를 취소하지 않는다. - 빌드 출력을 파일로 파이프하지 않는다. 지속적으로 보관할 오류 목록이 필요하면 콘솔 동작과 종료 상태의 신뢰성을 유지하도록 빌드 시스템의 기본 파일 로거 옵션을 사용한다. - 빌드 실패 일부를 검토할 때는 가장 먼저 발생한 오류부터 시작한다. 이후 실패는 앞선 오류의 결과인 경우가 많다. - 빌드가 고정 SDK를 확인하지 못하면 저장소의 부트스트랩 환경을 활성화하고 예상 SDK 버전이 활성화되었는지 확인한다. - 전체 저장소 빌드에 성공한 후에는 생성된 부트스트랩 실행 파일 또는 환경을 이후 검증에 사용한다. - 종단 간 검사에는 무관한 외부 프로젝트가 아니라 저장소의 예제 프로젝트를 사용한다. 빌드 결과물은 저장소가 정의한 결과물 디렉터리에 보관한다. 빌드가 성공한 것처럼 보이게 하려고 생성된 파일을 수동으로 편집하지 않는다. ## 변경을 테스트하고 새로 빌드한 명령을 실행한 뒤 마무리하기 변경된 동작과 저장소에서 생성한 빌드 엔진을 모두 입증하는 검증 순서를 사용한다. 1. 관련 단위 테스트 프로젝트를 실행하고, 유용한 경우 변경된 시나리오에 초점을 맞춘 테스트 필터를 사용한다. 2. 저장소 계약 또는 변경 범위에서 요구할 때만 전체 테스트 모음을 실행한다. 문서화된 실행 시간을 준수하고 정상적으로 오래 실행되는 모음을 조기에 취소하지 않는다. 3. 부트스트랩 환경을 통해 대표적인 저장소 예제를 빌드한다. 4. 새로 빌드한 명령줄 진입점을 도움말 표시 같은 무해한 명령으로 호출한다. 5. 전체 빌드가 경고나 오류 없이 완료되었는지 확인한다. 6. 차이를 다시 읽고 생성 파일 편집, 요청되지 않은 구성 변경, 호환성 위험, 누락된 문서가 있는지 확인한다. 완료에는 컴파일 성공뿐 아니라 증거가 필요하다. 실행한 빌드, 집중 테스트, 예제, 실행 파일 검사를 기록하고 수행할 수 없었던 검증을 명확히 밝힌다. 구성 요소 수준의 검사만 완료했다면 전체 검증을 완료했다고 주장하지 않는다.