dotnet高性能buffer

更新日期: 2020-12-22阅读: 1.6k标签: 性能

1 前言

我曾经写过《杂谈.netcore的Buffer相关新类型》的博客,简单介绍过BinaryPrimitives、Span<>,Memory<>,ArrayPool<>,Memorypool<>这些基础类型,在实际项目中,我们更需要的是更上层的高效缓冲区申请、buffer写入、buffer读取功能。本文将介绍如何利用这些基础类型,封装成易于使用的buffer相关操作类,这些类的源代码MemoryExtensions库里。


2 buffer知识

buffer的申请

通过经验与实验数据,根据不同场景与buffer大小,选择合适的申请方式。

申请式特点局限
stackalloc byte非常快速堆栈上分配内存块,容量小且在方法返回时缓冲区丢弃
new byte[]当小于1KB时速度快频繁创建导致内存碎片,GC压力大
ArrayPool.Rent适合大的缓冲区租赁,几乎无内存分配缓冲区小于1KB时,租赁不如new来得快

IBufferWriter接口

此接口支持获取缓冲区的写入Span或GetMemory给外部直接写入数据,写入完成之后调用Advance(int)方法,告诉writer实际的写入大小。

我们来对比一下MemoryStream的Write()方法,比如要写一个int类型的值,我们不得不将int转为4字节的byte[],然后传byte[]到Write()方法。这个4字节的byte[]是一个副作用,它的存在原于外部无法获取和扩大MemoryStream的缓冲区。


3 BufferWriter的实现

根据“buffer的申请”几种方式,我们实现多种不同的BufferWriter。

RecyclableBufferWriter

可回收的自动扩容BufferWriter,适合于大的缓冲区的场景。它的缓冲区通过ArrayPool来租赁,用完之后,要Dispose()归还到ArrayPool。优点是内存分配少,缺点是租赁比直接创建小的缓冲区还要慢。

Copy
var writer = new RecyclableBufferWriter<byte>(4); writer.Write((byte)1); writer.Write(new byte[] { 2, 3, 4 }); writer.WriteBigEndian(int.MaxValue); var writtern = writer.WrittenSpan; // 1,2,3,4,127,255,255,255 // return the buffer to pool writer.Dispose();

ResizableBufferWriter

自动扩容的BufferWriter,适合小的动态缓冲区的场景。它的冲区通过new Array来创建,通过Array.Resize扩容。优点是cpu性能好,缺点是内存分配高。

Copy
var writer = new ResizableBufferWriter<byte>(4); writer.Write((byte)1); writer.Write(new byte[] { 2, 3, 4 }); writer.WriteBigEndian(int.MaxValue); var writtern = writer.WrittenSpan; // 1,2,3,4,127,255,255,255

FixedBufferWriter

固定大小缓冲区,就是我们自己new的Array,包装为IBufferWriter对象。

Copy
var array = new byte[16]; var writer = array.CreateWriter(); writer.WriteBigEndian(18); writer.WriteBigEndian(2.01f);


4 IBufferWriter的扩展

经常会遇到将int、double等诸多数字类型写入IBufferWriter的场景,期间还涉及平台的BigEndian或LittleEndian,我们给IBufferWriter<byte>编写重载的扩展方法。

方法说明
WriteBigEndian(this IBufferWriter, short)short
WriteBigEndian(this IBufferWriter, int)int
WriteBigEndian(this IBufferWriter, long)long
WriteBigEndian(this IBufferWriter, ushort)ushort
WriteBigEndian(this IBufferWriter, uint)uint
WriteBigEndian(this IBufferWriter, ulong)ulong
WriteBigEndian(this IBufferWriter, float)float
WriteBigEndian(this IBufferWriter, double)double
WriteLittleEndian(this IBufferWriter, short)short
WriteLittleEndian(this IBufferWriter, int)int
WriteLittleEndian(this IBufferWriter, long)long
WriteLittleEndian(this IBufferWriter, ushort)ushort
WriteLittleEndian(this IBufferWriter, uint)uint
WriteLittleEndian(this IBufferWriter, ulong)ulong
WriteLittleEndian(this IBufferWriter, float)float
WriteLittleEndian(this IBufferWriter, double)double

5 ref BufferReader

同样的,我们也经常遇到从缓冲区中读取为int、double等诸多数字类型的场景,所以也需要设计一个高效的BufferReader。

Copy
public ref struct BufferReader { /// <summary> /// 未读取的数据 /// </summary> private ReadOnlySpan<byte> span; }

给它设计ReadLittleEndian和ReadBigEndian相关api

方法说明
ReadBigEndian(out short)short
ReadBigEndian(out int)int
ReadBigEndian(out long)long
ReadBigEndian(out ushort)ushort
ReadBigEndian(out uint)uint
ReadBigEndian(out ulong)ulong
ReadBigEndian(out float)float
ReadBigEndian(out double)double
ReadLittleEndian(out short)short
ReadLittleEndian(out int)int
ReadLittleEndian(out long)long
ReadLittleEndian(out ushort)ushort
ReadLittleEndian(out uint)uint
ReadLittleEndian(out ulong)ulong
ReadLittleEndian(out float)float
ReadLittleEndian(out double)double

6 关于MemoryExtensions库

本文提到的这些类或结构体,在MemoryExtensions库里都有实现,可以直接使用,其中BufferWriter技术已经在WebApiClient里大量应用。

原文:https://www.cnblogs.com/kewei/p/14285873.html

链接: https://fly63.com/article/detial/10107

提高js加载速度,实现js无阻塞加载方式,高性能的加载执行JavaScript

为解决JS加载速度慢,采用js的延时加载,和动态加载。由于js的堵塞特性,当浏览器在加载javascript代码时,不能同时做其他任何事情,如果javascript执行时间越久,浏览器等待响应的时间就越久。

如何提高CSS性能?CSS优化、提高性能提升总汇

如何提高CSS性能,根据页面的加载性能和CSS代码性能,主要表现为: 加载性能 (主要是从减少文件体积,减少阻塞加载,提高并发方面入手),选择器性能,渲染性能,可维护性。

前端性能优化_css加载会造成哪些阻塞现象?

css的加载是不会阻塞DOM的解析,但是会阻塞DOM的渲染,会阻塞link后面js语句的执行。这是由于浏览器为了防止html页面的重复渲染而降低性能,所以浏览器只会在加载的时候去解析dom树,然后等在css加载完成之后才进行dom的渲染以及执行后面的js语句。

2018 前端性能检查表

性能十分重要。然而,我们真的知道性能瓶颈具体在哪儿吗?是执行复杂的 JavaScript,下载缓慢的 Web 字体,巨大的图片,还是卡顿的渲染?研究摇树(Tree Shaking),作用域提升(Scope Hoisting)

高性能Javascript总结

Js高性能总结:加载和运行、数据访问、DOM编程、算法和流程控制、响应接口、Ajax 异步JavaScript和XML、编程实践...

优化网站性能规则_前端性能优化策略【网络加载、页面渲染】

前端网站性能优化规则:网络加载类、页面渲染类。包括:减少 HTTP 资源请求次数、减小 HTTP 请求大小、避免页面中空的 href 和 src、合理设置 Etag 和 Last-Modified、使用可缓存的 AJAX、减少 DOM 元素数量和深度等

前端性能的本质是什么?

性能一直以来是前端开发中非常重要的话题。随着前端能做的事情越来越多,浏览器能力被无限放大和利用:从 web 游戏到复杂单页面应用,从 NodeJS 服务到 web VR/AR 和数据可视化,前端工程师总是在突破极限

BigPipe_高性能流水线页面技术

BigPipe是一个重新设计的基础动态网页服务体系。大体思路是,分解网页成叫做Pagelets的小块,然后通过Web服务器和浏览器建立管道并管理他们在不同阶段的运行。这是类似于大多数现代微处理器的流水线执行过程:多重指令管线通过不同的处理器执行单元,以达到性能的最佳。

用CSS开启硬件加速来提高网站性能

你知道我们可以在浏览器中用css开启硬件加速,使GPU (Graphics Processing Unit) 发挥功能,从而提升性能吗?现在大多数电脑的显卡都支持硬件加速。鉴于此,我们可以发挥GPU的力量,从而使我们的网站或应用表现的更为流畅。

原生js实现懒加载并节流

像淘宝网站等,页面中有着大量图片,一次性全部加载这些图片会使浏览器发送大量请求和造成浪费。采用懒加载技术,即用户浏览到哪儿,就加载该处的图片。这样节省网络资源、提升用户体验、减少服务器压力。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!