优化利用可用资源是提高应用程序性能的重要策略之一。通过使用C#中的ArrayPool和MemoryPool类,可以最小化内存分配和垃圾收集开销,从而提高性能
本文将讨论这些资源、内存和对象池机制以及如何在C#中使用它们。要使用本文提供的代码示例,您应该在系统中安装Visual Studio 2019。如果您还没有副本,可以在此处下载VisualStudio2019
在Visual Studio中创建.NET核心控制台应用程序项目
首先,让我们在VisualStudio中创建一个.NET核心控制台应用程序项目。假设系统中安装了Visual Studio 2019,请按照下面概述的步骤在Visual Studio中创建新的.NET核心控制台应用程序项目
启动Visual StudioIDE。单击在“创建新项目”窗口中,从模板列表中选择“控制台应用程序(.NET Core)”显示。在在接下来显示的“配置新项目”窗口中,指定新项目的名称和位置。
这将在VisualStudio2019中创建一个新的.NET核心控制台应用程序项目。在本文的后续部分中,我们将使用这个项目来使用ArrayPool和MemoryPool
什么是ArrayPool?为什么需要它?
中的ArrayPool<;T>;类系统缓冲器命名空间是可重用托管阵列的高性能池。在数组经常被重用的情况下,它可以用来最小化分配和提高性能。ArrayPool<;T>;类定义为抽象类,如下面的代码段所示:
public abstract class ArrayPool<T>
想象一下这样一种情况:必须多次创建数组实例。这将导致垃圾收集器的开销,因为创建阵列时需要分配内存,而不再需要阵列时需要释放内存
这里正是ArrayPool<;T>;可以帮助节约资源的地方。您可以利用ArrayPool来保留一些数组,然后在需要时以线程安全的方式出租它们。每当您需要在代码中重复创建和销毁数组时,ArrayPool是一个不错的选择
在C中使用ArrayPool<;T>;类#
可以通过以下三种方式使用ArrayPool<;T>;类:
使用ArrayPool<;T>;.Shared属性获取共享ArrayPool<;T>;实例
下面的代码片段演示了如何从ArrayPool租用数组
var shared = ArrayPool<int>.Shared;
var rentedArray = shared.Rent(10);
在上面的示例中,名为rentedArray的整数数组将有10个元素;即,您可以在数组中存储10个整数值
您还可以编写前面的代码,如下所示
var rentedArray = ArrayPool<int>.Shared.Rent(10);
要将数组返回到池中,应按如下方式调用return方法
shared.Return(rentedArray);
以下是完整的代码列表供您参考:
static void Main(string[] args)
{
var shared = ArrayPool<int>.Shared;
var rentedArray = shared.Rent(10);
for (int i=0; i < 10; i++)
{
rentedArray[i] = i + 1;
}
for(int j=0;j < 10; j++)
{
Console.WriteLine(rentedArray[j]);
}
shared.Return(rentedArray);
Console.ReadKey();
}
ArrayPool<;T>;.Create方法可用于创建ArrayPool<;T>;类的新实例。下面的代码片段提供了一个示例
var arrayPool = ArrayPool<int>.Create(4, 10);
var rentedArray = arrayPool.Rent(10);
在C中创建自定义ArrayPool类#
您可以创建自己的ArrayPool实现,即自定义数组池类,如下所示
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();
}
}
在C中使用MemoryPool<;T>;类#
那个系统缓冲区内存池;T>;与系统内存命名空间表示内存池。当您的代码需要分配内存块,并且希望通过重用分配的内存而不是每次创建新的内存块来减轻GC的压力时,MemoryPool<;T>;是一个很好的选择
下面的代码片段演示了如何使用内存块。我们将创建一个内存池,然后从中租用一个内存块
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();
}
执行上述程序时,控制台窗口将显示数字1到10
阵列池<;T>;与内存池<;T>;
ArrayPool<;T>;类使用共享属性出租数组,而MemoryPool<;T>;类出租IMemoryOwner<;T>;实现。如果需要重复创建数组实例,则应使用ArrayPool<;T>。如果您使用的是内存实例,则应该使用MemoryPool<;T>;。内存池用于重用现有内存块;您可以使用它们动态分配内存块。阵列池管理阵列池,并在需要时租用它们
最后,请记住,对象池还可以通过回收对象而不是每次需要时重新创建对象来减少资源开销。您可以从我之前的文章中了解更多关于对象池和对象池设计模式的信息
如何在C#中做更多:如何在C中使用缓冲区类;如何在C中使用命名参数和可选参数;如何在C中使用AutoMapper;如何在C中使用lambda表达式;如何在C中实现简单的记录器;如何在C中实现存储库设计模式;如何在C中执行延迟初始化;如何在C中使用lambda表达式;如何在C中实现多态性在C中使用元组ţ探索C中的虚拟和抽象方法ţ如何在C中使用Dapper ORMţ如何在C中使用flyweight设计模式#