C#의 SortedList 컬렉션은 내부적으로 배열 기반으로 구현되어 있으며, 요소가 추가될 때마다 필요에 따라 용량(Capacity)이 자동으로 증가합니다. 따라서 실제 저장된 요소 수보다 용량이 큰 경우가 많습니다. 이럴 때 TrimToSize() 메서드를 호출하면 용량을 현재 실제 요소 수와 동일하게 줄여 불필요한 메모리 낭비를 방지할 수 있습니다.
TrimToSize() 메서드란?
TrimToSize()는 SortedList의 용량을 Count, 즉 현재 저장된 키-값 쌍의 개수와 같은 값으로 설정합니다. 예를 들어 용량이 16이고 요소가 10개인 SortedList에 이 메서드를 호출하면 용량이 10으로 줄어듭니다.
더 이상 새로운 요소를 추가하지 않을 것이라면 이 메서드를 통해 메모리 오버헤드를 최소화할 수 있습니다. 단, 이후 다시 요소를 추가하면 용량을 재확장해야 하므로 성능 비용이 발생할 수 있다는 점에 유의해야 합니다.
예제 1
다음 코드는 SortedList의 용량을 실제 요소 수로 설정하는 방법을 보여줍니다.
using System;
using System.Collections;
public class Demo {
public static void Main(String[] args) {
SortedList sortedList = new SortedList();
sortedList.Add("A", "1");
sortedList.Add("B", "2");
sortedList.Add("C", "3");
sortedList.Add("D", "4");
sortedList.Add("E", "5");
sortedList.Add("F", "6");
sortedList.Add("G", "7");
sortedList.Add("H", "8");
sortedList.Add("I", "9");
sortedList.Add("J", "10");
Console.WriteLine("SortedList 요소...");
foreach(DictionaryEntry d in sortedList) {
Console.WriteLine("Key = "+d.Key + ", Value = " + d.Value);
}
Console.WriteLine("\nSortedList를 순회하는 열거자...");
IDictionaryEnumerator demoEnum = sortedList.GetEnumerator();
while (demoEnum.MoveNext())
Console.WriteLine("Key = " + demoEnum.Key + ", Value = "+ demoEnum.Value);
Console.WriteLine("SortedList 키-값 쌍 개수 = "+sortedList.Count);
Console.WriteLine("SortedList 용량 = "+sortedList.Capacity);
sortedList.TrimToSize();
Console.WriteLine("SortedList 용량(변경 후) = "+sortedList.Capacity);
}
}
출력 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
SortedList 요소... Key = A, Value = 1 Key = B, Value = 2 Key = C, Value = 3 Key = D, Value = 4 Key = E, Value = 5 Key = F, Value = 6 Key = G, Value = 7 Key = H, Value = 8 Key = I, Value = 9 Key = J, Value = 10 SortedList를 순회하는 열거자... Key = A, Value = 1 Key = B, Value = 2 Key = C, Value = 3 Key = D, Value = 4 Key = E, Value = 5 Key = F, Value = 6 Key = G, Value = 7 Key = H, Value = 8 Key = I, Value = 9 Key = J, Value = 10 SortedList 키-값 쌍 개수 = 10 SortedList 용량 = 16 SortedList 용량(변경 후) = 10
실행 결과를 보면, 요소가 10개인 상태에서 초기 용량은 16이었지만 TrimToSize() 호출 후 용량이 정확히 10으로 줄어든 것을 확인할 수 있습니다.
예제 2
이번에는 두 개의 서로 다른 SortedList 객체를 사용해 동작을 비교해 보겠습니다.
using System;
using System.Collections;
public class Demo {
public static void Main(String[] args) {
SortedList list1 = new SortedList();
list1.Add("One", 1);
list1.Add("Two", 2);
list1.Add("Three", 3);
list1.Add("Four", 4);
list1.Add("Five", 5);
list1.Add("Six", 6);
list1.Add("Seven", 7);
list1.Add("Eight", 8);
list1.Add("Nine", 9);
list1.Add("Ten", 10);
Console.WriteLine("SortedList1 요소...");
foreach(DictionaryEntry d in list1) {
Console.WriteLine(d.Key + " " + d.Value);
}
Console.WriteLine("\nSortedList1의 키 목록...");
IList list = list1.GetKeyList();
foreach(string res in list)
Console.WriteLine(res);
Console.WriteLine("SortedList1 용량 = "+list1.Capacity);
list1.TrimToSize();
Console.WriteLine("SortedList1 용량(변경 후) = "+list1.Capacity);
SortedList list2 = new SortedList();
list2.Add("A", "Accessories");
list2.Add("B", "Books");
list2.Add("C", "Smart Wearable Tech");
list2.Add("D", "Home Appliances");
Console.WriteLine("\nSortedList2 요소...");
foreach(DictionaryEntry d in list2) {
Console.WriteLine(d.Key + " " + d.Value);
}
Console.WriteLine("\nSortedList2의 키 목록...");
list = list2.GetKeyList();
foreach(string res in list)
Console.WriteLine(res);
Console.WriteLine("SortedList2 용량 = "+list2.Capacity);
list2.TrimToSize();
Console.WriteLine("SortedList2 용량(변경 후) = "+list2.Capacity);
}
}
출력 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
SortedList1 요소... Eight 8 Five 5 Four 4 Nine 9 One 1 Seven 7 Six 6 Ten 10 Three 3 Two 2 SortedList1의 키 목록... Eight Five Four Nine One Seven Six Ten Three Two SortedList1 용량 = 16 SortedList1 용량(변경 후) = 10 SortedList2 요소... A Accessories B Books C Smart Wearable Tech D Home Appliances SortedList2의 키 목록... A B C D SortedList2 용량 = 16 SortedList2 용량(변경 후) = 4
정리
두 예제에서 알 수 있듯이, SortedList는 기본 생성 시 용량이 16으로 설정되며 요소 개수가 이를 초과하면 자동으로 확장됩니다. TrimToSize()를 호출하면 용량이 각각 실제 요소 수인 10과 4로 정확하게 조정되는 것을 확인할 수 있습니다. 데이터가 고정되어 더 이상 추가되지 않는 시점에 이 메서드를 활용하면 메모리를 효율적으로 관리할 수 있습니다.