홈으로 돌아가기

.NET 8 최적화를 위한 SearchValues와 FrozenCollections

이 기사는 .NET 8에서 SearchValues와 FrozenCollections를 핫 패스 검색 가속화를 위해 분석합니다. 벤치마크 제공 (문자열 13배, 딕셔너리 2배) 및 코드 예제. 읽기 중심 시나리오에서의 사용 권장사항.

SearchValues를 사용한 .NET 8의 13배 검색 가속
Advertisement 728x90

.NET 8 검색 최적화: SearchValues와 FrozenCollections로 핫패스 가속

.NET 8에서 SearchValues<T>FrozenSet<T>/FrozenDictionary<TKey, TValue> 같은 컬렉션이 새로 등장했습니다. 이들은 핫패스에서 오버헤드를 대폭 줄여줍니다. 생성 시 모든 무거운 작업을 미리 처리해 상수 시간 조회를 제공하며, 반복 분석 없이 빠르게 동작합니다. 초당 수백만 건의 작업을 처리하는 고성능 앱에 딱 맞아요.

SearchValues로 문자 검색 속도 폭발

기존 string.IndexOfAny는 매 호출마다 문자 집합을 재분석해 루프에서 오버헤드가 쌓입니다. SearchValues<char>는 한 번 생성으로 최적 검색 전략을 캐싱합니다.

초기화 시 .NET이 수행하는 작업:

Google AdInline article slot
  • 입력 집합 분석 (단일 문자, 범위, 다중 문자).
  • SIMD 지원 알고리즘 선택 (AVX2, SSE2).
  • 데이터 구조 구축 (비트마스크, 해시 테이블).
SearchValues<char> separators = SearchValues.Create(".,;!?");
ReadOnlySpan<char> input = "Hello, world!";
int index = input.IndexOfAny(separators);

데이터에 따라 검색 전략이 달라집니다:

  • 단일 문자 — 벡터화 검사.
  • 범위 (0-9A-Z) — O(1) 비트마스크.
  • 소규모 집합 (≤4 문자) — SIMD.
  • 대규모 집합 — 최적화된 해시 테이블.

벤치마크 결과 성능 향상이 뚜렷합니다:

| 시나리오 | IndexOfAny | SearchValues | 속도 향상 |

Google AdInline article slot

|----------|------------|--------------|----------|

| 짧은 문자열 | ~5 ns | ~5 ns | 1x |

| 긴 문자열 (2000자) | ~52 ns | ~4 ns | ~13x |

Google AdInline article slot

100자 이상 긴 문자열에서 반복 분석을 피할 때 가장 큰 효과를 봅니다.

FrozenCollections: 불변 해시 테이블

HashSet<T>Dictionary<TKey, TValue>는 리해싱과 경계 검사 같은 변경 오버헤드가 있습니다. FrozenSet<T>FrozenDictionary<TKey, TValue>는 읽기 전용에 최적화됐습니다.

생성 시:

  • 충돌 없는 완벽 해시 함수를 위한 키 분석.
  • 캐시 친화적 데이터 배치.
  • 런타임 불변성 검사 제거.

작은 컬렉션은 해싱 대신 비트마스크를 씁니다.

var dict = Enumerable.Range(0, 100000)
    .ToFrozenDictionary(x => x, x => $"Value {{x}}");

if (dict.TryGetValue(42, out string? value))
{
    Console.WriteLine(value);
}

벤치마크 (10만 요소):

| 작업 | Dictionary | HashSet | FrozenDictionary | FrozenSet |

|------|------------|---------|------------------|-----------|

| TryGetValue/Contains | 3.78 ns | 4.47 ns | 1.87 ns | 3.37 ns |

FrozenDictionary가 일반 Dictionary보다 2배 빠릅니다.

실제 활용 사례

SearchValues:

  • 고정 집합에 수백만 조회.
  • 로그 파싱, 토큰화, 유효성 검사.
  • 긴 문자열 (>100자).

FrozenCollections:

  • 시작 시 로드하는 정적 설정.
  • 조회 테이블 (에러 코드, 상태).
  • 조회 중심 워크로드 (수천 건 조회).

자주 변경되거나 드물게 호출될 때는 생성 비용이 이득을 상쇄하니 피하세요.

실전 구현 팁

앱 레벨에서 캐싱하세요:

public static class AppCache
{
    public static readonly SearchValues<char> UrlSafeChars = 
        SearchValues.Create("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~");
    
    public static readonly FrozenSet<string> ValidCurrencies = 
        new[] { "USD", "EUR", "GBP", "JPY", "CNY" }.ToFrozenSet();
}

유효성 검사 예시:

  • 이메일: SearchValues<char> invalidEmailChars = SearchValues.Create("()<>[]:;@\\,?\"");
  • TLD: FrozenSet<string> validTlds = LoadTldsFromConfig().ToFrozenSet();

항상 BenchmarkDotNet으로 프로파일링하세요. 작업량에 따라 이득이 달라집니다.

핵심 요약

  • SearchValues로 긴 문자열 검색 13배 빨라짐 (일회성 최적화).
  • FrozenDictionaryDictionary보다 TryGetValue 2배 빠름.
  • 핫패스 불변 집합에서 빛남.
  • 프로파일링 필수: 드문 호출엔 무의미.
  • SIMD와 완벽 해싱으로 미드/시니어 개발자 필수 기술.

— Editorial Team

Advertisement 728x90

다음 읽기