Take advantage of array pooling and memory pooling in C# to reduce allocations and improve the performance of your applications Credit: Thinkstock Optimal usage of available resources is one of the most important strategies for improving application performance. By using the ArrayPool and MemoryPool classes in C#, you can minimize memory allocations and garbage collection overhead and hence improve performance. This article discusses these resource, memory, and object pooling mechanisms and how to work with them in C#. To work with the code examples provided in this article, you should have Visual Studio 2019 installed in your system. If you don’t already have a copy, you can download Visual Studio 2019 here. Create a .NET Core console application project in Visual Studio First off, let’s create a .NET Core console application project in Visual Studio. Assuming Visual Studio 2019 is installed in your system, follow the steps outlined below to create a new .NET Core console application project in Visual Studio. Launch the Visual Studio IDE. Click on “Create new project.” In the “Create new project” window, select “Console App (.NET Core)” from the list of templates displayed. Click Next. In the “Configure your new project” window shown next, specify the name and location for the new project. Click Create. This will create a new .NET Core console application project in Visual Studio 2019. We’ll use this project to work with ArrayPool and MemoryPool in the subsequent sections of this article. What is ArrayPool? Why is it needed? The ArrayPool class in the System.Buffers namespace is a high-performance pool of reusable managed arrays. It can be used to minimize allocations and improve performance in cases where arrays are often reused. The ArrayPool class is defined as an abstract class as shown in the code snippet that follows: public abstract class ArrayPool<T> Imagine a situation where you must create instances of an array several times. This will result in overhead for the garbage collector because memory needs to be allocated when the array is created and then deallocated when the array is no longer needed. Here’s exactly where an ArrayPool can help conserve resources. You can take advantage of an ArrayPool to reserve some arrays and then rent them out in a thread-safe manner when asked for. An ArrayPool is a good choice whenever you’re having to repeatedly create and destroy arrays in your code. Use the ArrayPool class in C# You can use the ArrayPool class in the following three ways: Using the ArrayPool.Shared property to get a shared ArrayPool instance Using the static ArrayPool.Create method to create a new instance of ArrayPool Creating a custom ArrayPool class by extending ArrayPool The following code snippet illustrates how you can rent an array from the ArrayPool. var shared = ArrayPool<int>.Shared; var rentedArray = shared.Rent(10); In the above example, the integer array named rentedArray will have 10 elements; i.e., you can store 10 integer values in the array. You can also write the preceding code as shown below. var rentedArray = ArrayPool<int>.Shared.Rent(10); To return the array back to the pool, you should call the Return method as follows. shared.Return(rentedArray); Here is the complete code listing for your reference: static void Main(string[] args) { var shared = ArrayPool.Shared; var rentedArray = shared.Rent(10); for (int i=0; i shared.Return(rentedArray); Console.ReadKey(); } The ArrayPool.Create method can be used to create a new instance of the ArrayPool class. The following code snippet provides an example. var arrayPool = ArrayPool<int>.Create(4, 10); var rentedArray = arrayPool.Rent(10); Create a custom ArrayPool class in C# You can create your own implementation of ArrayPool, i.e., a custom array pool class as shown below. public class CustomArrayPool<T> : ArrayPool<T> { public override T[] Rent(int minimumLength) { throw new NotImplementedException(); } public override void Return(T[] array, bool clearArray = false) { throw new NotImplementedException(); } } Use the MemoryPool class in C# The System.Buffers.MemoryPool class pertaining to the System.Memory namespace represents a memory pool. MemoryPool is a good choice when your code needs to allocate blocks of memory and you would like to reduce the pressure on the GC by reusing the allocated memory rather than creating new memory blocks each time. The following code snippet illustrates how you can work with memory blocks. We’ll create a memory pool and then rent a memory block from it. static void Main(string[] args) { var memoryPool = MemoryPool<int>.Shared; var arrayPool = ArrayPool<int>.Create(4, 10); var rentedArray = arrayPool.Rent(10); for (int i=0; i < 10; i++) { rentedArray[i] = i + 1; } for(int j=0;j < 10; j++) { Console.WriteLine(rentedArray[j]); } arrayPool.Return(rentedArray); Console.ReadKey(); } When you execute the above program, the numbers 1 to 10 will be displayed at the console window. ArrayPool vs. MemoryPool The ArrayPool class rents out arrays using the Shared property, while the MemoryPool class rents out IMemoryOwner implementations. You should use ArrayPool if you need to create array instances repeatedly. And you should use MemoryPool if you’re working with Memory instances. Memory pools are used to reuse existing memory blocks; you can use them to allocate memory blocks dynamically. Array pools manage a pool of arrays and rent them when asked for. Finally, keep in mind that object pooling can also be used to reduce resource overhead by recycling objects rather than recreating them each time they’re needed. You can learn more about object pools and the object pool design pattern from my earlier article here. How to do more in C#: How to use the Buffer class in C# How to use HashSet in C# How to use named and optional parameters in C# How to benchmark C# code using BenchmarkDotNet How to use fluent interfaces and method chaining in C# How to unit test static methods in C# How to refactor God objects in C# How to use ValueTask in C# How to use immutability in C How to use const, readonly, and static in C# How to use data annotations in C# How to work with GUIDs in C# 8 When to use an abstract class vs. interface in C# How to work with AutoMapper in C# How to use lambda expressions in C# How to work with Action, Func, and Predicate delegates in C# How to work with delegates in C# How to implement a simple logger in C# How to work with attributes in C# How to work with log4net in C# How to implement the repository design pattern in C# How to work with reflection in C# How to work with filesystemwatcher in C# How to perform lazy initialization in C# How to work with MSMQ in C# How to work with extension methods in C# How to us lambda expressions in C# When to use the volatile keyword in C# How to use the yield keyword in C# How to implement polymorphism in C# How to build your own task scheduler in C# How to work with RabbitMQ in C# How to work with a tuple in C# Exploring virtual and abstract methods in C# How to use the Dapper ORM in C# How to use the flyweight design pattern in C# Related content feature What is Rust? Safe, fast, and easy software development Unlike most programming languages, Rust doesn't make you choose between speed, safety, and ease of use. Find out how Rust delivers better code with fewer compromises, and a few downsides to consider before learning Rust. By Serdar Yegulalp Nov 20, 2024 11 mins Rust Programming Languages Software Development how-to Kotlin for Java developers: Classes and coroutines Kotlin was designed to bring more flexibility and flow to programming in the JVM. Here's an in-depth look at how Kotlin makes working with classes and objects easier and introduces coroutines to modernize concurrency. By Matthew Tyson Nov 20, 2024 9 mins Java Kotlin Programming Languages analysis Azure AI Foundry tools for changes in AI applications Microsoft’s launch of Azure AI Foundry at Ignite 2024 signals a welcome shift from chatbots to agents and to using AI for business process automation. By Simon Bisson Nov 20, 2024 7 mins Microsoft Azure Generative AI Development Tools news Microsoft unveils imaging APIs for Windows Copilot Runtime Generative AI-backed APIs will allow developers to build image super resolution, image segmentation, object erase, and OCR capabilities into Windows applications. By Paul Krill Nov 19, 2024 2 mins Generative AI APIs Development Libraries and Frameworks Resources Videos