如何在 C# 中使用 ArrayPool 和 MemoryPool
对资源的可复用是提升应用程序性能的一个非常重要的手段,比如本篇要分享的 ArrayPool 和 MemoryPool,它们就有效的减少了内存使用和对GC的压力,从而提升应用程序性能。
什么是 ArrayPool
System.Buffers 命名空间下提供了一个可对 array 进行复用的高性能池化类 ArrayPool<T>
,在经常使用 array 的场景下可使用 ArrayPool<T>
来减少内存占用,它是一个抽象类,如下代码所示:
public abstract class ArrayPool<T>
{
}
可以想象一下你的业务场景中需要多次实例化 array,这么做有什么后果呢? 很显然每一次 new array 都会在托管堆上分配,同时当 array 不再使用时还需要 GC 去释放,而 ArrayPool<T>
就是为了解决此事而生的,它在池中动态维护若干个 array 对象,当你需要 new array
的时候只需从池中获取即可。
使用 ArrayPool<T>
可以通过下面三种方式来使用 ArrayPool<T>
。
通过
ArrayPool<T>.Shared
属性来获取ArrayPool<T>
实例。通过
ArrayPool<T>.Create()
来生成ArrayPool<T>
实例。通过继承
ArrayPool<T>
来生成一个自定义子类。
下面的代码展示了如何从 ArrayPool 中获取一个 size >= 10
的 array 数组。
var shared = ArrayPool<int>.Shared;
var rentedArray = shared.Rent(10);
上面的代码一定要注意,虽然只租用了 10 个 size,但底层会返回 2的倍数
的size , 也就是图中的 2* 8 = 16。
当什么时候不需要 rentedArray 了,记得再将它归还到 ArrayPool 中,如下代码所示。
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
你也可以通过重写 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();
}
}
使用 MemoryPool<T>
System.Memory
命名空间下提供了一个内存池对象 MemoryPool<T>
,在这之前你需要每次都 new 一个内存块出来,同时也增加了 GC 的负担,有了 MemoryPool<T>
之后,你需要的内存块直接从池中拿就可以了。
static void Main(string[] args)
{
var memoryPool = MemoryPool<int>.Shared;
var rentedArray = memoryPool.Rent(10);
for (int i = 0; i < 10; i++)
{
rentedArray.Memory.Span[i] = i + 1;
}
for (int j = 0; j < 10; j++)
{
Console.WriteLine(rentedArray.Memory.Span[j]);
}
Console.ReadKey();
}
ArrayPool<T>
vs MemoryPool<T>
从上面的演示可以看出, ArrayPool<T>
是以 array
的形式向外租借,而 MemoryPool<T>
则是以 内存块
的方式向外租借,所以在重复使用 array 的场景下可以优选 ArrayPool<T>
来提高性能,如果你的代码是以 Memory<T>
这种内存块的形式多次使用则优先使用 MemoryPool<T>
。
更多精彩,欢迎订阅
译文链接:https://www.infoworld.com/article/3596289/how-to-use-arraypool-and-memorypool-in-c.html
如何在 C# 中使用 ArrayPool 和 MemoryPool的更多相关文章
- 我是如何在SQLServer中处理每天四亿三千万记录的
首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...
- 如何在SpringBoot中使用JSP ?但强烈不推荐,果断改Themeleaf吧
做WEB项目,一定都用过JSP这个大牌.Spring MVC里面也可以很方便的将JSP与一个View关联起来,使用还是非常方便的.当你从一个传统的Spring MVC项目转入一个Spring Boot ...
- 如何在latex 中插入EPS格式图片
如何在latex 中插入EPS格式图片 第一步:生成.eps格式的图片 1.利用visio画图,另存为pdf格式的图片 利用Adobe Acrobat裁边,使图片大小合适 另存为.eps格式,如下图所 ...
- 如何正确的使用json?如何在.Net中使用json?
什么是json json是一种轻量级的数据交换格式,由N组键值对组成的字符串,完全独立于语言的文本格式. 为什么要使用json 在很久很久以前,调用第三方API时,我们通常是采用xml进行数据交互,但 ...
- [原创]如何在Parcelable中使用泛型
[原创]如何在Parcelable中使用泛型 实体类在实现Parcelable接口时,除了要实现它的几个方法之外,还另外要定义一个静态常量CREATOR,如下例所示: public static cl ...
- 如何在springMVC 中对REST服务使用mockmvc 做测试
如何在springMVC 中对REST服务使用mockmvc 做测试 博客分类: java 基础 springMVCmockMVC单元测试 spring 集成测试中对mock 的集成实在是太棒了!但 ...
- 如何在tomcat中如何部署java EE项目
如何在tomcat中如何部署java EE项目 1.直接把项目复制到Tomcat安装目录的webapps目录中,这是最简单的一种Tomcat项目部署的方法,也是初学者最常用的方法.2.在tomcat安 ...
- 【转】我是如何在SQLServer中处理每天四亿三千万记录的
原文转自:http://blog.jobbole.com/80395/ 首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文 ...
- 如何在JAVA中实现一个固定最大size的hashMap
如何在JAVA中实现一个固定最大size的hashMap 利用LinkedHashMap的removeEldestEntry方法,重载此方法使得这个map可以增长到最大size,之后每插入一条新的记录 ...
随机推荐
- C语言之库函数的模拟与使用
C语言之库函数的模拟与使用 在我们学习C语言的过程中,难免会遇到这样的一种情况: 我们通常实现一个功能的时候,费尽心血的写出来,却有着满满的错,这时却有人来告诉你说:这个功能可以用相应的库函数来实现. ...
- 解决M1 MacBook无法使用pip安装Numpy
问题描述 Python官方已发布支持M1 Apple Silicon的版本,但是在使用pip包管理工具安装一些依赖时发生了错误,这里面就包括在科学计算领域常用的numpy.pandas等.目前可以通过 ...
- cobaltstrike的使用
0x01 介绍 Cobalt Strike是一款渗透测试神器,常被业界人称为CS神器.Cobalt Strike已经不再使用MSF而是作为单独的平台使用,它分为客户端与服务端,服务端是一个,客户端可以 ...
- 【php代码审计】熊海cms1.0
0x01 环境安装 1. 熊海cms1.0 (http://js.down.chinaz.com/201503/xhcms_v1.0.rar) 2.seay代码审计工具 3. phpstudy (ph ...
- 【情人节选帽子】TCS34725颜色传感器和Python图形界面编程(STM32 HAL库)
截图 描述: l STM32 HAL库编程 l 使用模拟IIC通信,方便程序移植 l Python界面编写,蘑菇头的帽子是什么颜色 l STM32 HAL库串口通信 l Python界面使用 ...
- print函数与转义字符
一.print函数 作用:1.输出数字. print(520) 2.输出字符串.(注意:输出字符串要添加单引号.双引号或三引号,告诉编译器可直接输出,不用分析) print('you are so b ...
- CSS ? Layout Module : CSS 布局模型
1 1 1 https://www.w3.org/TR/css-grid-1/ CSS Grid Layout Module Level 1 W3C Working Draft, 19 May 201 ...
- OOP & 模块化, 多态, 封装
OOP 面向对象编程 (OOP) 是用抽象方式创建基于现实世界模型的一种编程模式.它使用先前建立的范例,包括模块化,多态和封装几种技术. 在 OOP 中,每个对象能够接收消息,处理数据和发送消息给其他 ...
- CSS border gradient color All In One
CSS border gradient color All In One CSS Gradient Borders border-image-source & border-image-sli ...
- npm & cli & cp: no such file or directory
npm & cli & cp: no such file or directory empty files bug https://npm.runkit.com/hui-cli htt ...