c# 高级编程 7章167页 【数组池】

347 阅读2分钟

如何高效地使用数组

  1. 使用Span<T>
  2. 使用ArrayPool

ArrayPool

  • 应用场景:程序需要创建和销毁很多数组的时候
  • 好处:减少垃圾收集器的工作
  • 原理:ArrayPool在多个桶中为大小类似的数组管理内存

创建ArrayPool

两种方式来获取数组池:

  • 自定义数组池,静态Create()方法
  • 预定义数组池,Shared属性

自定义数组池

指定,需要下一个桶之前,一个桶能够有的最大数组数量和最大数组长度

ArrayPool<int> customPool = ArrayPool<int>.Create(maxArrayLength:40000, maxArraysPerBucket:10);

预定义数组池

ArrayPool<int> sharedPool = ArrayPool<int>.Shared;

从数组池中租用和归还内存

Rent()

  • 如果池中有内存,则返回该内存。如果池中没有内存,则先给池分配内存,然后再返回该内存。
  • 不管申请的长度是多大,数组的返回尺寸总是以下可能数值: 16、32、64、128、256、512、1024、2048、4096、8192等 Return()
  • 返回时最好清除内容,虽然CPU时间用得多点,但是可以避免使下个这片内存的使用者读取到不该读取的数据
        static void Main()
        {
            for (int i = 0; i < 10; i++)
            {
                int arrayLength = (i + 1) << 10;
                int[] arr = ArrayPool<int>.Shared.Rent(arrayLength);
                Console.WriteLine($"requested an array of {arrayLength} and received {arr.Length}");
                for (int j = 0; j < arrayLength * j; j++)
                {
                    arr[j] = j;
                }
                ArrayPool<int>.Shared.Return(arr, clearArray: true);
            }
        }   

输出

requested an array of 1024 and received 1024
requested an array of 2048 and received 2048
requested an array of 3072 and received 4096
requested an array of 4096 and received 4096
requested an array of 5120 and received 8192
requested an array of 6144 and received 8192
requested an array of 7168 and received 8192
requested an array of 8192 and received 8192
requested an array of 9216 and received 16384
requested an array of 10240 and received 16384