最近研究了一下.net core 2.1的基础类库,发现它引入了一个System.Buffers名字空间,里面提供了一系列比较实用的对象,便简单的管中窥豹浏览一下。

ArrayPool<T>

ArrayPool<T>是一个数组类型的对象池,本身ArrayPoo<T>是一个抽象类,但他有一个默认的实现ArrayPoo<T>. Shared,使用方法如下:

var pool   = ArrayPool<byte>.Shared;
var buffer = pool.Rent(2048);
try
{
    //使用buffer
}
finally
{
    pool.Return(buffer);
    //归还buffer后不要再使用
}

方法比较简单:

  1. 通过Rent从对象池中申请buffer
  2. 使用完后,通过Return将buffer归还至对象池

微软的文档上并没有详细描述默认的ArrayPoo<T>的对象申请算法,但由于其代码是开源的,还是可以到github上看到其实现方式的。

初略的看了一下,貌似也并不复杂,和传统的对象池的维护方式也差不多:

  1. 系统维持着一个对象池
  2. 调用Rent的时候,首先会到对象池中查看是否有合适的对象(至少要满足最小长度),如果有则直接返回对象池中的对象,并将其从对象池中移除
  3. 调用Return时,将对象放置到对象池,从而可以作为下次Rent的候选对象

注:这里只记录了主要相关功能,实际算法比这个复杂。另外由于没有很详细看实现方式,如要描述不正确的地方欢迎指正

也就是说,return后的对象,很可能被别的地方rent走,因此可能导致读写冲突。(类似于c语言中的野指针,但仍然是安全的,不会造成内存错误)

MemoryPool<T>

除了ArrayPool外,System.Buffers名字空间下还提供了一个MemoryPool,它的使用方式和ArraPool比较类似,基本示例如下:

var pool   = MemoryPool<byte>.Shared;
var buffer = pool.Rent(2048);
try
{
    var memory = buffer.Memory;
    //use Memory<byte>
}
finally
{
    buffer.Dispose();
}

整个过程还是非常类似的,不过释放的时候是调用的Dispose方法,用起来实际要更加方便点。不过这里申请到的是Memory<T>对象,可能有的地方不像byte[]那样适用 。

关于MemoryPool的实现,我在github上找了一下,还没有看到。不过由于它返回的是Memory<T>,理论上来讲应该是有更高的效率。(例如,可以把一个大段的buffer分成多个memory返回,从而减少申请新对象)

BinaryPrimitives

BinaryPrimitives位于System.Buffers.Binary名字空间下,它提供了一系列数字和字节互相转换的函数。

  

它的主要好处是是提供了常用BigEndian类型的数字的支持,在网络编程或者文件解析的方式的时候非常实用,免得造轮子了。

Utf8Parser、Utf8Formatter和Base64

这三个类位于System.Buffers.Text下,它主要用于utf8编码和base64编码下的常用类型的读写,如datetime,guid,bool等,并且支持常用的序列化方式。

这几个类目前官方文档都介绍的不是很详细,目前要详细了解的话只能看代码。由于篇幅所限,这里也不做更多的介绍,以后用到的时候再写单独的文章介绍它们。

参考文章:

  1. ArrayPool<T> Class
  2. Pooling large arrays with ArrayPool

.net core中的System.Buffers名字空间的更多相关文章

  1. [译]如何在.NET Core中使用System.Drawing?

    你大概知道System.Drawing,它是一个执行图形相关任务的流行的API,同时它也不属于.NET Core的一部分.最初是把.NET Core作为云端框架设计的,它不包含非云端相关API.另一方 ...

  2. .net core中关于System.Text.Json的使用

    在.Net Framework的时候序列化经常使用Newtonsoft.Json插件来使用,而在.Net Core中自带了System.Text.Json,号称性能更好,今天抽空就来捣鼓一下. 使用起 ...

  3. EF Core中关于System.Linq.Dynamic.Core的使用(转载)

    项目中经常用到组合条件查询,根据用户配置的查询条件进行搜索,拼接SQL容易造成SQL注入,普通的LINQ可以用表达式树来完成,但也比较麻烦.有个System.Linq.Dynamic.Core用起来比 ...

  4. C和C++中的名字空间和作用域

    C和C++中的名字空间和作用域 C语言中有名字空间这个概念吗? 提到名字空间(或者可能更普遍的叫法,命名空间),很可能先想到的是C++,甚至是C#.C中没有名字空间吧?一开始我也是这样认为的,直到我看 ...

  5. Docker的名字空间

    名字空间是 Linux 内核一个强大的特性.每个容器都有自己单独的名字空间,运行在其中的应用都像是在独立的操作系统中运行一样.名字空间保证了容器之间彼此互不影响. pid 名字空间 不同用户的进程就是 ...

  6. TransactionScope事务处理方法介绍及.NET Core中的注意事项

    作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/10170712.html 今天在写CzarCms的UnitOfWork的使用使用到了这个Transacti ...

  7. TransactionScope事务处理方法介绍及.NET Core中的注意事项 SQL Server数据库漏洞评估了解一下 预热ASP.NET MVC 的VIEW [AUTOMAPPER]反射自动注册AUTOMAPPER PROFILE

    TransactionScope事务处理方法介绍及.NET Core中的注意事项   作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/10170712.ht ...

  8. 【转】TransactionScope事务处理方法介绍及.NET Core中的注意事项

    什么是TransactionScope呢? TransactionScope作为System.Transactions的一部分被引入到.NET 2.0.同时SqlClient for .NET Cor ...

  9. C++名字空间/C++命名空间

    0.序言 名字空间是C++提供的一种解决符号名字冲突的方法. 一个命令空间是一个作用域,在不同名字空间中命名相同的符号代表不同的实体. 通常,利用定义名字空间的办法,可以使模块划分更加方便,减少模块间 ...

随机推荐

  1. 鼠标样式 cursor 全总结

    本文地址:https://www.cnblogs.com/veinyin/p/10752805.html  最常用的 key  pointer   cursor: key; // 除了pointer, ...

  2. 360 / 小米 / 百度 随身wifi Ubuntu 下作为无线网卡使用

    这篇文章说得其实很好了,http://www.freemindworld.com/blog/2013/131010_360_wifi_in_linux.shtml 不过因为专利问题,官网貌似不直接提供 ...

  3. javascript的this分别代表什么

    鉴于大家对this到底代表的是什么有疑问,现在将我个人理解的this的情况整理如下.有错误请指正. 第一种情况:  如果是一个全局的function,则this相当于window对象. 这个打印出来的 ...

  4. 通俗理解决策树中的熵&条件熵&信息增益

    参考通俗理解决策树算法中的信息增益 说到决策树就要知道如下概念: 熵:表示一个随机变量的复杂性或者不确定性. 假如双十一我要剁手买一件衣服,但是我一直犹豫着要不要买,我决定买这件事的不确定性(熵)为2 ...

  5. Ansible Tower系列 二(安装 Tower)【转】

    文档:http://docs.ansible.com/ansible-tower/ 安装前检查 python版本为2.6 保持网络畅通 内存预留充足 安装用户为root 软件下载 下载地址:http: ...

  6. com.alibaba.fastjson.JSONException: autoType is not support.

    解决办法:https://github.com/alibaba/fastjson/wiki/enable_autotype 文摘如下: 一.添加autotype白名单 添加白名单有三种方式,三选一,如 ...

  7. JMeter出现“the target server failed to respond“的解决办法

    今天用jmeter压测执行过程中遇到一个报错如下: 解决方案如下: 1. 修改执行计划中,HTTP请求的Implementation为HttpClient4. 2. 保存执行计划 3. 修改JMete ...

  8. re模块逐步进阶

    Windows 10家庭中文版,Python 3.6.4, 正则表达式,自己一直的水平是 知道,但不熟悉,简单的也能写,复杂的就需要看资料了,距离灵活运用还是差那么一些的. 于是,今天(180831) ...

  9. MySQL一问一答

    一.问:如果有一张表,里面有个字段为id的自增主键,当已经向表里面插入了10条数据之后,删除了id为8,9,10的数据,再把mysql重启,之后再插入一条数据,那么这条数据的id值应该是多少,是8,还 ...

  10. 基于用Path.Combine的优化

    Path.Combine: 什么时候会用到Path.Combine呢?,当然是连接路径字符串的时候! 所以下面的代码可以完美的工作: public static void Main() { strin ...