runtime: ArrayPool.Shared.Rent should support returning a zero-inited array

Currently calling ArrayPool<T>.Shared.Rent does not guarantee that the returned buffer is zero-inited. While good for performance, this could cause correctness issues in applications, especially those that simply use byte[] xyz = ArrayPool<byte>.Shared.Rent(...) as a drop-in replacement for byte[] xyz = new byte[...].

I propose changing the signature of ArrayPool.Rent(int minimumLength) to ArrayPool.Rent(int minimumLength, bool clearArray = true). Thus the default behavior is to zero-init the returned array, and consumers who want the highest possible performance and don’t care about the initial values can pass false for this parameter. (I know we shouldn’t default optional arguments to anything other than default(T). Haven’t fully reconciled this API design mentally yet.)

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 4
  • Comments: 23 (22 by maintainers)

Most upvoted comments

@koszeggy even “new” arrays returned by the array pool are not guaranteed to be zero inited. You’d still have to clear manually anyway. See https://github.com/dotnet/coreclr/pull/24504 for more details.

We should also look at these suggestions above when we do that. https://github.com/dotnet/corefx/issues/25843#issuecomment-351226440

There are number of other things that are less than ideal about the ArrayPool:

  • You have to fetch a static and invoke a virtual method to do anything - both of which are relatively expensive operations
  • It would be better for the API to rent System.Memory instead of array. It would allow more efficient underlying implementation. E.g. the underlying implementation would be able to reuse space for int[] and byte[].
  • It would be nice to have a option for a life-time tracking (borrow the ideas from Snowflake project) that would guarantee safety and avoid use-after-free (perhaps in combination with supporting Roslyn analyzer). It would be superior to just the zero-filling idea discussed here.

If we are rethinking how ArrayPool works, we may want to address all of them.