어레이 풀

Dec 15 2022
요즘에는 배열을 거의 사용하지 않습니다. 대부분의 경우 더 많은 기능을 제공하고 후드 아래의 배열을 기반으로 하는 List<T>를 사용합니다.

요즘에는 배열을 거의 사용하지 않습니다. 대부분의 경우 더 많은 기능을 제공하고 후드 아래의 배열을 기반으로 하는 List<T>를 사용합니다. 하지만 많은 객체를 다루다 보면 성능이 관건이 되는 상황이 있습니다.

나를 놀라게 한 것은 일반 배열이 목록보다 두 배 효율적이며 여전히 ArrayPool로 최적화할 수 있다는 것입니다.

이 기사에서는 코드 예제 및 벤치마킹 성능과 함께 ArrayPool을 사용하는 방법을 보여줍니다.

코드 저장소

어레이풀이란?

ArrayPool은 어레이 유형의 인스턴스를 재사용할 수 있는 리소스 풀입니다. 버퍼(어레이)를 임대 및 반환하는 데 사용할 수 있습니다. 메모리와 GARBAGE COLLECTOR 가 많은 배열을 자주 생성하고 삭제할 때 성능이 향상됩니다 . 이 클래스는 스레드로부터 안전하며 동시에 사용할 수 있습니다. 풀로 돌아가는 동안 배열 콘텐츠를 지우거나 지우지 않도록 선택할 수 있습니다. 지우는 데 시간이 더 걸리지만 상황에 따라 매번 빈 배열을 가져와야 할 수도 있습니다.

사용 방법

풀 메모리에서 어레이에 액세스하는 방법에는 두 가지가 있습니다.

첫 번째이자 가장 간단한 방법은 ArrayPool Shared 속성을 사용하는 것입니다.

ArrayPool<T>.공유

풀의 기본 구현을 얻게 됩니다. 다양한 크기의 배열을 포함합니다. 그것은 당신이 요청한 것보다 더 큰 배열을 반환할 수 있지만 확실히 더 작지는 않습니다. 공유 풀은 어레이를 재사용하는 편리한 방법이지만 더 나은 방법이 있습니다.

보다 효율적인 방법은 create 메소드를 사용하여 풀을 초기화하는 것입니다.

ArrayPool<T>.Create()

ArrayPool<T>.Create(int maxArrayLength, int maxArraysPerBucket)

Create 메서드는 풀의 사용자 지정 인스턴스를 반환합니다. 재사용하려면 다른 위치에서 액세스하려면 캐시해야 합니다. 매개변수화된 방법은 최상의 성능을 달성하는 데 도움이 될 수 있습니다. 길이가 maxArrayLength 이하인 배열을 maxArraysPerBucket 크기의 버킷으로 그룹화하는 인스턴스를 생성합니다 .

C#의 배열 풀링을 활용하여 할당을 줄이고 응용 프로그램의 성능을 향상하십시오.

기준

이것은 간단한 테스트입니다. 새 어레이를 만드는 것과 풀에서 대여하는 것의 차이점을 비교해 보겠습니다. 각각의 경우에 1_000_000 요소 컬렉션을 반복합니다. 또한 배열의 성능 이점을 보여주기 위해 벤치마크에 List<T>를 포함할 것입니다.

코드 저장소

기준

결론

나를 가장 놀라게 한 것은 일반 배열이 속도와 메모리 사용 측면에서 목록보다 두 배 더 효율적이라는 것입니다. 그리고 여전히 ArrayPool로 최적화할 수 있습니다. 수영장을 사용하는 것은 분명히 갈 길입니다.

표준 어레이를 사용하는 것과 풀에서 사용하는 것 사이에는 눈에 띄는 시간 차이가 있습니다. 시차는 매번 새로운 어레이를 생성할 때 메모리를 할당하는 데 필요한 시간입니다. 물론 메모리 할당에도 차이가 있습니다. ArrayPool은 새 메모리를 할당할 필요가 없습니다. 동일한 블록을 재사용합니다.

경고로 '캐싱 없는 사용자 정의 풀'을 추가하여 매번 새 풀을 생성할 때 어떤 일이 발생하는지 확인할 수 있습니다. 매번 새로운 어레이를 생성하는 것과 기본적으로 동일합니다.

이 간단한 예에서는 공유 ArrayPool과 사용자 지정 ArrayPool 간의 성능 차이를 보여주기 어렵습니다. 크기가 다른 많은 배열을 사용하는 경우 눈에 띕니다.

ArrayPool을 사용하는 것이 항상 가장 편리한 것은 아니지만 때로는 필요할 때 많은 컴퓨팅 성능을 절약할 수 있습니다.