콘텐츠로 이동

C# FrozenDictionary & FrozenSet — 읽기 전용 고성능 컬렉션

FrozenDictionary<TKey, TValue>FrozenSet<T>은 .NET 8에서 도입된 불변 고성능 컬렉션입니다. 생성 시 내부 구조를 최적화해 이후 조회 속도를 Dictionary보다 빠르게 만들지만, 생성 후 수정은 불가합니다.


using System.Collections.Frozen;
// FrozenDictionary 생성
var config = new Dictionary<string, string>
{
["host"] = "localhost",
["port"] = "5432",
["db"] = "mydb"
}.ToFrozenDictionary();
// 읽기 전용 — Add/Remove 없음
string host = config["host"];
bool hasPort = config.ContainsKey("port");
// FrozenSet 생성
var allowedRoles = new[] { "admin", "editor", "viewer" }
.ToFrozenSet(StringComparer.OrdinalIgnoreCase);
bool isAllowed = allowedRoles.Contains("Admin"); // true

연산DictionaryFrozenDictionary
생성빠름느림 (최적화 포함)
조회 (TryGetValue)기준최대 ~2× 빠름
메모리기준비슷하거나 적음
수정가능불가

내부적으로 키 분포를 분석해 완전 해시 함수(perfect hashing)를 생성하거나, 작은 컬렉션은 선형 탐색을 사용합니다.


3.1 애플리케이션 시작 시 한 번 생성

섹션 제목: “3.1 애플리케이션 시작 시 한 번 생성”
public static class CountryLookup
{
private static readonly FrozenDictionary<string, Country> _map =
LoadCountries().ToFrozenDictionary(c => c.Code);
public static Country? Find(string code)
=> _map.TryGetValue(code, out var c) ? c : null;
}
public class PermissionChecker(IEnumerable<string> permissions)
{
private readonly FrozenSet<string> _permissions =
permissions.ToFrozenSet(StringComparer.Ordinal);
public bool Has(string permission) => _permissions.Contains(permission);
}
var methodHandlers = new Dictionary<string, Func<HttpContext, Task>>
{
["GET"] = HandleGet,
["POST"] = HandlePost,
["DELETE"] = HandleDelete,
}.ToFrozenDictionary(StringComparer.OrdinalIgnoreCase);

// 대소문자 무시 FrozenDictionary
var headers = rawHeaders.ToFrozenDictionary(
StringComparer.OrdinalIgnoreCase);
// 숫자 키 FrozenDictionary
var statusMessages = new Dictionary<int, string>
{
[200] = "OK",
[404] = "Not Found",
[500] = "Internal Server Error",
}.ToFrozenDictionary();

항목ImmutableDictionaryFrozenDictionary
불변성
With 연산✓ (새 인스턴스 반환)
조회 성능Dictionary보다 느림Dictionary보다 빠름
목적불변 수정 가능 컬렉션읽기 전용 최고 성능

  • 애플리케이션 시작 시 데이터를 로드하고 이후 읽기만 하는 경우
  • 핫 경로(hot path)에서 딕셔너리 조회 성능이 병목인 경우
  • 설정 값, 코드 테이블, 권한 목록 등 정적 데이터

FrozenDictionaryFrozenSet은 “한 번 빌드, 많이 읽기” 패턴에 최적화된 컬렉션입니다. 정적 데이터 조회가 빈번한 경우 Dictionary를 그대로 두지 말고 ToFrozenDictionary()로 교체하면 의미 있는 성능 향상을 얻을 수 있습니다.