Proper usage of ArrayPool<T> with a reference type
Asked Answered
R

1

6

What is the proper way to use ArrayPool with reference types?

I was assuming that it would be full of objects that were just 'newed up' with the default constructor.

For example, in the code below, all the Foobars are null when you first rent from the ArrayPool.

2 Questions:

  1. Since the objects returned from .Rent are initially all null, do I need to fill up the array pool with initialized objects first?

  2. When returning the rented objects do I need to clear each object? For example, foobar.Name = null; foobar.Place = null etc...

public class Program
{
    public class Foobar {
        public string Name {get;set;}
        public string Place {get;set;}
        public int Index {get;set;}
    }

    public static void Main()
    {
        ArrayPool<Foobar> pool = ArrayPool<Foobar>.Shared;
        var foobars = pool.Rent(5);
        foreach(var foobar in foobars) {
            // prints "true"
            Console.WriteLine($"foobar is null? ans={foobar == null}");
        }       
    }
}
Rufus answered 5/8, 2019 at 23:29 Comment(0)
T
8

Since the objects returned from .Rent are initially all null, do I need to fill up the array pool with initialized objects first?

You don't need to, no. But you likely should, at least, do null checks on anything returned from the array.

I was assuming that it would be full of objects that were just 'newed up' with the default constructor.

No. They will be default(T) - i.e. null. It seems like you are thinking of ArrayPool as being a pool of objects. That is true, but mainly it is a pool of arrays. It is primarily trying to avoid the overhead of allocating and de-allocating arrays (not the objects inside the arrays).

When returning the rented objects do I need to clear each object?

You don't need to, no. These is no generic answer as to whether you should or not - that depends on your specific problem space.

When returning to the pool, you can indicate whether the data should be cleared or not. I'd suggest passing true as the value of clearArray if you don't want your data to be stored in the pool.

clearArray Boolean

Indicates whether the contents of the buffer should be cleared before reuse. If clearArray is set to true, and if the pool will store the buffer to enable subsequent reuse, the Return(T[], Boolean) method will clear the array of its contents so that a subsequent caller using the Rent(Int32) method will not see the content of the previous caller. If clearArray is set to false or if the pool will release the buffer, the array's contents are left unchanged.

Alternatively, you can take care of clearing the buffer yourself before calling Return. I'd also suggest reading this link.

If you want the pool to contain the objects (to avoid the cost of newing them up again) you can do so - but make sure you set clearArray to false (or leave it at its default).

Tressa answered 5/8, 2019 at 23:36 Comment(2)
Ok, thank you. I was thinking ArrayPool would be a good way to reduce allocations of objects and was not thinking about minimizing array allocations. This clears things up.Rufus
nuget.org/packages/Microsoft.Extensions.ObjectPool may be of interest @Rufus .Tressa

© 2022 - 2024 — McMap. All rights reserved.