6. index와 range 그리고 Span
.NET Core 2.1부터 .NET에 대한 마이크로소프트 주요 목표 중 하나는 성능과 리소스 활용의 향상이며 Span<T>는 그 목표의 일환 중 하나입니다.
Array 구현할 때 기존에 존재하는 Array객체에서 일부분만을 필요로 하는 경우 기존 객체를 그대로 복사해 새로운 Array를 생성하고 필요한 처리를 수행하는 경우가 있습니다. 그러나 이러한 방법은 메모리에 같은 객체를 반복해 생성하게 된다는 측면에서 그다지 효휼적인 방법이라고는 할 수 없습니다.
위와 같이 전체가 아닌 일부분의 요소만을 필요로 한다면 span을 사용함으로써 성능과 효율성을 기대할 수 있습니다. 다만 Span은 Collection이 아닌 Array를 대상으로만 사용할 수 있습니다.
Span에 관해 알아보기 전 우선 이와 관련하여 Index와 range에 대해 알아볼 필요가 있습니다. Index는 Array에서 위치를 식별하는 수단으로 사용될 수 있으며 C# 8.0에서는 Array에서 요소의 Index를 식별하기 위한 2가지 기능과 2개의 Index를 사용하는 Item의 range기능을 추가하였습니다.
● Index
아래 예제는 Array에서 Indexer를 통해 값을 가져오는 가장 일반적인 방법을 보여주고 있습니다.
string[] names = new string[] { "홍길동", "홍길영", "홍길석" };
string name = names[1];
이때 위와 동일한 목적으로 위치를 식별하기 위해 Index Type을 아래와 같은 형태로 사용할 수 있습니다.
Index i = new(value: 1);
string[] names = new string[] { "홍길동", "홍길영", "홍길석" };
string name = names[i];
Console.WriteLine(name); //홍길영
위 예제는 Array의 시작점부터 1에 해당하는 Index를 찾은 것으로 'Index i = 1'과 동일합니다. 만약 Array의 끝에서부터 Counting하는 것이라면 아래와 같이 Index를 생성할 수 있습니다.
Index i = new(value: 1, fromEnd: true);
● Range
Index는 요소의 위치를 정확히 지정하는 반면 Range는 요소의 범위를 지정하는 것이며 Range의 생성자를 통해 시작점과 끝점을 Index로 지정하거나
Range r1 = new(start: new Index(0), end: new Index(2));
Range r2 = new(start: 0, end: 2);
C# 8.0이상이라면 ..을 사용해 간략히 Range를 생성할 수 있습니다.
Range r1 = 0..2;
정적 메서드를 사용하는 경우는 정수나 Index Type을 전달하여 Range의 Start와 End를 지정할 수 있고
Range r1 = Range.StartAt(0);
Range r2 = Range.EndAt(0);
C# 8.0이상이라면 역시 ..을 사용해 동일한 Range를 생성할 수 있습니다.
Range r1 = 0..;
Range r2 = ..2;
● Sapn
위에서 Index와 Range를 이해했으면 이제 Span을 사용할 준비가 된 것입니다. Span은 내부적으로 char Type을 다루는 문자열(string) 혹은 int Array에서 확장 메서드로 사용됩니다.
string names = "홍길순,홍길영";
int firstIdx = names.IndexOf(',');
int lastIdx = (names.Length - firstIdx) - 1;
string name1 = names.Substring(0, firstIdx);
string name2 = names.Substring(names.Length - lastIdx, lastIdx);
Console.WriteLine(name1); //홍길순
Console.WriteLine(name2); //홍길영
우선 위 예제는 range사용 없이 Substring()메서드를 통해 문자열에서 이름 2개를 분리하는 경우를 방법을 보여주고 있습니다. 같은 기능을 range로 처리하려면 다음과 같이 구현할 수 있습니다.
string names = "홍길순,홍길영";
int firstIdx = names.IndexOf(',');
int lastIdx = (names.Length - firstIdx) - 1;
ReadOnlySpan<char> namesSpan = names.AsSpan();
ReadOnlySpan<char> firstNameSpan = namesSpan[0..firstIdx];
ReadOnlySpan<char> lastNameSpan = namesSpan[^lastIdx..^0];
Console.WriteLine(firstNameSpan.ToString());
Console.WriteLine(lastNameSpan.ToString());
'.NET' 카테고리의 다른 글
[.NET] 닷넷 Type 사용하기 - 7. reflection 과 attributes (0) | 2022.06.26 |
---|---|
[.NET] 닷넷 Type 사용하기 - 6. 네트워크 리소스 활용 (0) | 2022.06.26 |
[.NET] 닷넷 Type 사용하기 - 4. Collection 사용 (0) | 2022.06.26 |
[.NET] 닷넷 Type 사용하기 - 3. 정규식(regular expressions) (0) | 2022.06.26 |
[.NET] 닷넷 Type 사용하기 - 2. 날짜와 시간 (0) | 2022.06.26 |