GitHub Copilot의 에이전트 모드를 사용하여 저성능 코드 리팩터링
개발자는 GitHub Copilot의 에이전트 모드를 사용하여 기능이 유지되고 코드 품질이 향상되도록 하면서 성능이 낮은 코드를 안전하게 리팩터링할 수 있습니다.
비고
GitHub Copilot의 요청 모드를 사용하여 성능 병목 상태를 분석하고 에이전트 모드를 사용하여 변경 내용을 구현하기 전에 최적화 계획을 수립합니다. 이 방법을 사용하면 리팩터링이 신중하고 안전하게 수행됩니다.
에이전트 모드란?
GitHub Copilot의 에이전트 모드는 코드베이스 전체에서 복잡한 리팩터링 작업을 실행하기 위해 자율적으로 작동합니다. 채팅 패널에서 지침 및 제안을 제공하는 Ask 모드와 달리 에이전트 모드는 제안된 업데이트를 코드 파일에서 직접 편집으로 구현합니다.
에이전트 모드는 지침에 따라 파일을 편집하고, 변경 내용을 적용하고, 테스트를 실행하고, 명령을 실행할 수 있습니다. 프로젝트 컨텍스트를 이해하고 여러 파일에서 일관성을 유지하여 리팩터링 변경 내용이 기존 기능을 중단하지 않도록 할 수 있습니다.
에이전트 모드는 종속성, 에지 사례 및 테스트를 신중하게 처리해야 하는 다단계 최적화 전략을 구현하는 데 적합합니다. 에이전트 모드는 필요한 컨텍스트를 자동으로 정의하고 성능 향상 목표를 달성하는 데 필요한 단계를 실행합니다.
에이전트 모드를 사용하여 성능이 낮은 코드 리팩터링
에이전트 모드를 사용하여 Ask 모드 분석 중에 식별된 최적화 전략을 구현할 수 있습니다. 에이전트 모드는 원래 기능을 유지하고 코드 성능을 향상하면서 여러 리팩터링 단계를 자동으로 실행할 수 있습니다.
성능이 낮은 코드를 리팩터링하기 위한 전략
다음은 에이전트 모드를 사용하여 성능이 낮은 코드를 리팩터링하기 위한 주요 전략입니다.
데이터 구조 최적화: 선형 검색과 같은 비효율적인 데이터 구조를 사전 또는 해시 집합과 같은 최적화된 대안으로 바꾸도록 에이전트 모드에 지시합니다.
캐싱 메커니즘 구현: 에이전트 모드에서 중복 계산 또는 비용이 많이 드는 작업을 방지하기 위해 지능형 캐싱을 추가하도록 합니다.
N+1 쿼리 패턴 제거: 에이전트 모드를 사용하여 성능 향상을 위해 여러 쿼리 또는 작업을 일괄 처리 작업으로 통합합니다.
비동기 처리 추가: 에이전트 모드에서 차단 작업을 비동기 패턴으로 변환하여 확장성 및 응답성을 향상시킵니다.
알고리즘 복잡성 감소: 시간 복잡성이 더 높은 보다 효율적인 방법을 사용하기 위해 에이전트 모드 리팩터링 알고리즘이 있어야 합니다.
보안 보장: 에이전트 모드에 성능 최적화가 보안 취약성을 발생하거나 기존 보안 검사를 우회하지 않는지 확인하도록 지시합니다.
기능 유지 관리: 에이전트 모드를 사용하여 기존의 모든 비즈니스 논리 및 오류 처리를 유지하면서 성능 특성을 개선합니다.
에이전트 모드는 성능이 낮은 코드를 리팩터링하라는 메시지를 표시합니다.
에이전트 모드를 사용하여 성능이 낮은 코드를 리팩터링하는 경우 프롬프트는 구체적이고 실행 가능하며 안전성 고려 사항을 포함해야 합니다. 다음은 성능이 낮은 코드를 리팩터링할 때 프롬프트에 포함할 수 있는 자연어 텍스트의 몇 가지 예입니다.
준비 및 안전
- "리팩터링하기 전에 선택한 성능에 중요한 메서드의 현재 동작을 확인하는 단위 테스트를 만듭니다."
- "선택한 코드를 분석하여 보안에 미치는 영향을 분석하고 리팩터링이 모든 보안 검사를 유지하도록 합니다."
- "선택한 코드에 대한 성능 최적화를 만들기 전에 백업 분기를 만들고 기존 테스트를 실행합니다."
기본 최적화 작업
- "선택한 메서드를 리팩터링하여 선형 검색 대신 사전 조회를 사용하여 성능을 향상시킵니다."
- "비용이 많이 드는 작업에 대한 캐싱 메커니즘을 구현하여 선택한 코드를 최적화합니다."
- "선택한 N+1 쿼리 패턴을 일괄 처리 작업으로 바꿔 데이터베이스 호출을 줄입니다."
- "확장성을 높이기 위해 선택한 차단 작업을 비동기 패턴으로 변환합니다."
고급 최적화 패턴
- "스레드 보안을 유지하면서 처리량을 개선하기 위해 병렬 처리를 사용하여 선택한 코드를 리팩터링합니다."
- "선택한 알고리즘을 최적화하여 O(n²)에서 O(n log n) 이상으로 시간 복잡성을 줄입니다."
- "선택한 비효율적인 데이터 구조를 더 빠른 조회를 위해 최적화된 컬렉션으로 바꿉니다."
- "초기화 성능을 향상시키기 위해 지연 로드 패턴을 사용하도록 선택한 코드를 리팩터링합니다."
품질 및 유효성 검사
- "리팩터링 후 모든 테스트를 실행하고 동일한 기능을 유지하면서 성능이 향상되었는지 확인합니다."
- "리팩터링된 코드가 Microsoft의 C# 코딩 규칙 및 성능 모범 사례를 따르는지 확인합니다."
- "리팩터링된 코드가 원래 구현과 동일한 보안 특성을 유지하는지 확인합니다."
- "리팩터링을 통해 달성된 개선을 측정하는 성능 벤치마크를 만듭니다."
성능이 낮은 코드를 리팩터링하기 위한 에이전트 모드 워크플로
다음 워크플로에서는 에이전트 모드를 사용하여 성능이 낮은 코드를 안전하게 리팩터링하는 방법을 보여 줍니다.
작업 영역 준비
깨끗한 git 분기에서 작업 중이고 기존 작업이 커밋되었는지 확인합니다. 클린 분기에서 작업하면 필요한 경우 변경 내용을 쉽게 되돌릴 수 있습니다. Ask 모드에서 분석한 성능 병목 현상이 포함된 파일로 이동합니다.
안전 조치 설정
변경하기 전에 에이전트 모드에 기존 단위 테스트를 만들거나 실행하도록 요청합니다.
"성능을 위해 리팩터링하기 전에 현재 동작을
ProcessOrders확인하기 위해 메서드에 대한 포괄적인 단위 테스트를 만듭니다."이 단계에서는 리팩터링이 기능을 유지하는지 확인하는 안전망이 있는지 확인합니다.
간단한 최적화 단계로 시작
선형 검색 바꾸기와 같은 위험 수준이 낮은 변경으로 시작합니다.
O(n) 대신 O(1) 성능을 위해 선형 검색을 사전 조회로 바꿔
GetProductById메서드를 리팩터링합니다.에이전트 모드는 코드를 분석하고 사전 기반 접근 방식을 구현하여 조회 성능을 크게 향상합니다.
캐싱 전략 구현
캐싱 최적화를 계속 진행합니다.
"짧은 기간 내에 동일한 통화에
GetExchangeRate대한 중복 API 호출을 방지하기 위해 메서드에 지능형 캐싱을 추가합니다."에이전트 모드는 적절한 캐싱 논리를 만들어 비용이 많이 드는 외부 서비스 호출을 줄입니다.
알고리즘 복잡성 최적화
더 복잡한 성능 문제를 해결합니다.
"단일 패스로
CalculateDiscounts대량 작업을 처리하는 보다 효율적인 알고리즘을 사용하도록 중첩된 루프를 리팩터링합니다."에이전트 모드는 비효율적인 중첩 루프를 식별하고 최적화된 알고리즘으로 바꿉니다.
변경 내용 유효성 검사
각 주요 리팩터링 단계 후에 변경 내용의 유효성을 검사합니다.
"모든 단위 테스트 및 성능 벤치마크를 실행하여 리팩터링된 코드가 성능 향상과 동일한 결과를 생성하는지 확인합니다."
에이전트 모드는 테스트를 실행하고 해결해야 하는 오류를 보고할 수 있습니다.
검토 및 반복
문제가 발견되면 수정에 대한 특정 지침을 제공합니다.
"성능 테스트는 한계 개선만을 보여 줍니다. 리팩터링된 캐싱 논리를 검토하고 캐시 적재가 효과적으로 활용되고 있는지 확인합니다."
에이전트 모드는 성능 메트릭을 분석하고 예상되는 개선을 달성하기 위해 필요한 수정을 수행합니다.
이 구조화된 접근 방식을 사용하면 각 단계에서 유효성 검사를 통해 성능 최적화를 안전하고 체계적으로 수행할 수 있습니다.
성능이 낮은 코드를 리팩터링하기 위한 일반적인 시나리오
일반적인 시나리오를 검토하면 성능 리팩터링에 에이전트 모드를 효과적으로 사용하는 방법을 이해하는 데 도움이 될 수 있습니다.
데이터 액세스 패턴 최적화(N+1 쿼리 제거)
N+1 쿼리를 초래하는 데이터 액세스 패턴은 성능이 심각하게 저하될 수 있습니다. 일괄 처리 데이터 검색으로 리팩터링하면 효율성이 크게 향상될 수 있습니다.
이 시나리오는 다음 코드 조각을 사용하여 설명될 수 있습니다.
foreach (var order in orders)
{
decimal price = GetProductPrice(order.ProductId); // database call
order.TotalPrice = order.Quantity * price;
}
프로파일링 분석에 따르면 GetProductPrice (데이터베이스를 쿼리하는) 대량 주문을 처리할 때 병목 현상이 발생합니다.
에이전트 모드를 사용하여 제품 가격 조회를 일괄 처리하여 코드를 리팩터링할 수 있습니다. 다음은 그 예입니다.
에이전트 모드 프롬프트: "제품 가격 조회를 일괄 처리하여 N+1 쿼리 패턴을 제거하도록 이 코드를 최적화합니다."
에이전트는 다음과 같이 코드를 리팩터합니다.
- 모든 고유한 제품 ID를 수집합니다.
- 단일 데이터베이스 호출에서 가격을 가져옵니다.
- 가격을 주문에 다시 매핑합니다.
리팩터링된 코드는 다음 코드 조각과 유사해야 합니다.
var productIds = orders.Select(o => o.ProductId).Distinct().ToList();
var priceCache = GetProductPrices(productIds).ToDictionary(p => p.ProductId, p => p.Price);
foreach (var order in orders)
{
if (priceCache.TryGetValue(order.ProductId, out decimal price))
{
order.TotalPrice = order.Quantity * price;
}
}
다음과 같은 개선 사항을 확인합니다.
- 업데이트된 코드는 필요한 모든 가격 조회를 단일 데이터베이스 호출로 일괄 처리합니다.
- 누락된 제품에 대한 오류 처리가 제대로 유지됩니다.
- 이 코드는 동일한 비즈니스 논리를 유지하면서 성능을 크게 향상합니다.
비효율적인 알고리즘 바꾸기
더 나은 성능을 위해 선형 검색을 최적화된 데이터 구조로 바꿔야 합니다.
이 시나리오는 다음 코드 조각을 사용하여 설명될 수 있습니다.
public Product FindProductByName(string name)
{
foreach (var product in products) // O(n) linear search
{
if (product.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
{
return product;
}
}
return null;
}
에이전트 모드를 사용하여 O(1) 조회 사전을 사용하여 코드를 리팩터링할 수 있습니다. 다음은 그 예입니다.
에이전트 모드 프롬프트: "제품 조회를 O(1) 성능으로 최적화하기 위해 사전 기반 접근 방식을 사용하세요."
에이전트는 다음과 같이 코드를 리팩터합니다.
- 제품 이름을 제품 개체에 매핑하는 사전을 초기화합니다.
- 조회에 사전을 사용합니다.
리팩터링된 코드는 다음 코드 조각과 유사해야 합니다.
private readonly Dictionary<string, Product> _productsByName =
products.ToDictionary(p => p.Name, StringComparer.OrdinalIgnoreCase);
public Product FindProductByName(string name)
{
_productsByName.TryGetValue(name, out Product product);
return product;
}
다음과 같은 개선 사항을 확인합니다.
- 조회 시간 복잡성이 O(n)에서 O(1)로 향상됩니다.
- 문자열 비교 논리는 적절한 비교자를 사용하여 유지됩니다.
- 초기화 비용은 여러 조회 작업에 대해 분할 상환됩니다.
비동기 처리 구현
확장성을 높이기 위해 차단 작업을 비동기 패턴으로 변환합니다. 비동기 프로그래밍을 사용하도록 동기 코드를 리팩터링하면 응답성과 확장성이 향상될 수 있습니다.
이 시나리오는 다음 코드 조각을 사용하여 설명될 수 있습니다.
public void ProcessOrderNotification(Order order)
{
var emailContent = GenerateEmailContent(order);
Thread.Sleep(1000); // simulate email service delay
SendEmail(order.CustomerEmail, emailContent);
}
에이전트 모드를 사용하여 코드를 비동기 패턴으로 변환하여 코드를 리팩터링할 수 있습니다. 다음은 그 예입니다.
에이전트 모드 프롬프트: "이 동기 전자 메일 처리를 비동기식으로 변환하여 확장성 및 응답성을 향상시킵니다."
에이전트는 다음과 같이 코드를 리팩터합니다.
- 메서드를 비동기로 만드세요.
- 비동기 작업에 사용합니다
await.
리팩터링된 코드는 다음 코드 조각과 유사해야 합니다.
public async Task ProcessOrderNotificationAsync(Order order)
{
var emailContent = await GenerateEmailContentAsync(order);
await Task.Delay(1000); // simulate async email service delay
await SendEmailAsync(order.CustomerEmail, emailContent);
}
다음과 같은 개선 사항을 확인합니다.
- 모든 호출자는 비동기 메서드를 기다리도록 업데이트됩니다.
- 비동기 패턴은 호출 체인 전체에 일관되게 적용됩니다.
- 오류 처리 및 취소 토큰은 필요한 경우 올바르게 구현됩니다.
보안 및 품질 고려 사항
성능 리팩터링에 에이전트 모드를 사용하는 경우 항상 보안 및 품질 영향을 고려합니다.
보안 모범 사례
성능을 위해 리팩터링할 때 다음 보안 사례를 고려합니다.
입력 처리 유효성 검사: 성능 최적화가 입력 유효성 검사를 무시하거나 삽입 취약성을 도입하지 않도록 합니다.
권한 부여 검사 유지: 최적화 중에 보안 관련 유효성 검사가 실수로 제거되거나 약화되지 않는지 확인합니다.
보안 캐싱 방법: 캐시된 데이터가 중요한 정보를 노출하거나 무단 액세스 경로를 만들지 않도록 합니다.
감사 내역 유지 관리: 성능 향상 중에 로깅 및 모니터링 논리가 유지되는지 확인합니다.
코드 품질 표준
기업은 일반적으로 특정 코딩 표준 집합을 채택합니다. 지침이 없는 경우 Microsoft는 사용자가 따를 수 있는 C# 코딩 규칙에 대한 권장 사항을 게시합니다.
다음 지침에 따라 높은 코드 품질을 유지합니다.
설정된 패턴을 따릅니다. 리팩터링된 코드가 팀의 코딩 표준 및 아키텍처 패턴을 따르는지 확인합니다.
가독성 유지: 성능이 향상되더라도 최적화된 코드를 읽을 수 있고 유지 관리할 수 있는지 확인합니다.
오류 처리 유지: 성능 최적화 중에 모든 오류 처리 논리가 유지되는지 확인합니다.
복잡한 최적화를 문서화: 향후 유지 관리자를 위해 눈에 띄지 않는 성능 최적화를 설명하는 주석을 추가합니다.
에이전트 모드 안전 지침
에이전트 모드는 강력하지만 신중하게 감독해야 합니다.
리팩터링 전
- 항상 Feature 브랜치에서 작업하세요.
- 포괄적인 테스트 적용 범위가 있는지 확인합니다.
- 요청 모드 분석에서 최적화 계획을 검토합니다.
- 성능 특성 및 비즈니스 논리를 이해합니다.
리팩터링 중
- 큰 변환 대신 증분 변경을 합니다.
- 다음으로 진행하기 전에 각 최적화 단계의 유효성을 검사합니다.
- 생성된 코드를 검토하여 정확성 및 성능 향상을 확인합니다.
- 자주 테스트하여 회귀를 조기에 발견합니다.
리팩터링 후
- 기준 비교를 포함하여 포괄적인 성능 벤치마크를 실행합니다.
- 팀 구성원과 함께 코드 검토를 수행합니다.
- 보안 및 기능 특성의 유효성을 검사합니다.
- 성능 향상을 반영하도록 설명서를 업데이트합니다.
에이전트 모드를 강력한 도우미로 처리
에이전트 모드는 복잡한 성능 최적화를 수행할 수 있지만 사용자 감독이 필요합니다.
- 모든 변경 내용을 적용하기 전에 검토합니다.
- 성능 향상이 측정 가능하고 중요한지 확인합니다.
- 보안 및 기능 요구 사항이 충족되는지 확인합니다.
- 미세한 행동 변화를 감지하려면 철저히 테스트합니다.
에이전트 모드는 성능 최적화를 가속화하지만 신중한 검토, 테스트 및 측정의 필요성을 대체하지는 않습니다.
요약
GitHub Copilot의 에이전트 모드를 사용하면 개발자가 코드 품질 및 기능을 유지하면서 성능이 낮은 코드를 효율적으로 리팩터링할 수 있습니다. Ask 모드의 분석 인사이트를 에이전트 모드의 실행 기능과 결합하여 애플리케이션 성능, 확장성 및 효율성을 체계적으로 개선할 수 있습니다. 성공의 열쇠는 명확한 지침을 제공하고, 안전 사례를 유지 관리하며, 포괄적인 테스트 및 성능 측정을 통해 모든 변경 내용의 유효성을 철저히 검사하는 것입니다.