Array Pool main

Array Pool

Nowadays, we rarely use arrays. In most cases, we use List<T>, which provides more functionality and is based on an array under the hood. But there are situations when performance is the key while dealing with many objects.

What has surprised me is that a plain array is twice as efficient as a List, and it can still be optimized with ArrayPool.

In this article, I will show you how to use ArrayPool with code examples and benchmarking performance.

Code Repository

ArrayPool is a resource pool that allows reusing instances of array types. You can use it to Rent and Return buffers(arrays). It will improve performance when you frequently create and destroy arrays, which are heavy on memory and GARBAGE COLLECTOR. This class is thread-safe, and you can use it concurrently. While returning to the pool, you can choose to clear or not array content. Clearing will take more time, but your situation might require getting an empty array each time.

There are two ways of accessing arrays from pool memory.

The first and simplest is to use the ArrayPool Shared property.

ArrayPool<T>.Shared

You will get the default implementation of the pool. It contains arrays of different sizes. It can return a larger array than you have requested but certainly not smaller. A shared pool is a convenient way to reuse arrays, but there are better ones.

The more efficient way is to initialize your pool using create methods.

ArrayPool<T>.Create()

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

Create method returns a custom instance of the pool. You must cache it to access it from different locations to reuse it. The parameterized method can help achieve the best performance. It will create an instance that groups arrays of length no more than maxArrayLength into buckets of size maxArraysPerBucket.

Take advantage of array pooling in C# to reduce allocations and improve the performance of your applications.

This is a straightforward test. We will compare the differences between creating a new array and renting it from the pool. In each case, we will iterate over a collection of 1_000_000 elements. I will also include List<T> in the benchmark to show the performance advantages of arrays.

Code Repository

https://github.com/krossa/ArrayPoolBenchmark
Benchmark results
benchmark

What has surprised me the most is that a plain array is twice as efficient as a List in terms of speed and memory usage. And it can still be optimized with ArrayPool. Using a pool is obviously the way to go.

There is a noticeable time difference between using a standard array and one from the pool. The time difference is the time required to allocate memory when creating a new array each time. Of course, there is also a difference in memory allocation. ArrayPool does not need to allocate new memory. It reuses the same block.

As a warning, I have added ‘Custom Pool Without Caching’ so you can see what happens when you create a new pool each time. It is basically the same thing as creating a new array each time.

In this simple example, it is hard to show the performance difference between shared and custom ArrayPool. It would be noticeable when many arrays of different sizes are used.

Using ArrayPool may not always be the most convenient, but sometimes it can save you a lot of computing power when needed.

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store