ReadOnlySpan<T> 可以说现在高性能操作的重要基石

其原理有兴趣的同学可以看 2018 的介绍Span<T>文章

其为了保障大家安全使用做了相应的限制

那么有没方法绕过呢?

在class中持有 ReadOnlySpan

直接持有是不可能的,本身为 ref struct 就保障了大家写不出持有它的代码

但是我们可以玩骚操作,无法持有你,我们可以创造一个一模一样的你

如下面代码,我们获取span 对应的指针

public unsafe class ReadOnlySpanReaderBuffer<T>
{
internal void* _buffer;
internal int _length; public ReadOnlySpanReaderBuffer(Span<T> span)
{
_buffer = Unsafe.AsPointer(ref span.GetPinnableReference());
_length = span.Length;
} public ReadOnlySpanReaderBuffer(ReadOnlySpan<T> span)
{
_buffer = Unsafe.AsPointer(ref MemoryMarshal.GetReference(span));
_length = span.Length;
}

在需要使用的时候通过指针重新创建一个一模一样的span

public ReadOnlySpan<T> Readed
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new ReadOnlySpan<T>(_buffer, _length);
}

将 Span 转换成 Memory

同样出于安全考虑,默认Span<T> 无法转换成 Memory<T>

但是我们可以玩骚操作,无法转换你,我们可以创造一个

首先我们需要建立一个Memory的基础类, 通过它来告诉 Memory<T> 如何拿去我们从 Span<T>里面偷出来的指针

public sealed unsafe class UnmanagedMemoryManager<T> : MemoryManager<T>
{
private readonly T* _pointer;
private readonly int _length; public UnmanagedMemoryManager(Span<T> span)
{
fixed (T* ptr = &MemoryMarshal.GetReference(span))
{
_pointer = ptr;
_length = span.Length;
}
} public UnmanagedMemoryManager(T* pointer, int length)
{
if (length < 0) throw new ArgumentOutOfRangeException(nameof(length));
_pointer = pointer;
_length = length;
} public UnmanagedMemoryManager(nint pointer, int length) : this((T*)pointer.ToPointer(), length) { } public override Span<T> GetSpan() => new Span<T>(_pointer, _length); // 一切的关键就在这个方法
public override MemoryHandle Pin(int elementIndex = 0)
{
if (elementIndex < 0 || elementIndex >= _length)
throw new ArgumentOutOfRangeException(nameof(elementIndex));
return new MemoryHandle(_pointer + elementIndex);
} public override void Unpin() { } protected override void Dispose(bool disposing) { }
}

在需要使用的时候通过指针重新创建一个一模一样的Memory

public ReadOnlyMemory<T> ReadedMemory
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new UnmanagedMemoryManager<T>((IntPtr)_buffer, _length).Memory;
}

道路千万条,安全第一条,大家慎用骚操作啊

骚操作之 持有 ReadOnlySpan 数据的更多相关文章

  1. 闪电侠 Netty 小册里的骚操作

    前言 即使这是一本小册,但基于"不提笔不读书"的理念,仍然有必要总结一下.此小册对于那些"硬杠 Netty 源码 却不曾在千万级生产环境上使用实操"的用户非常有 ...

  2. 如何在命令长度受限的情况下成功get到webshell(函数参数受限突破、mysql的骚操作)

    0x01 问题提出 还记得上篇文章记一次拿webshell踩过的坑(如何用PHP编写一个不包含数字和字母的后门),我们讲到了一些PHP的一些如何巧妙地绕过数字和字母受限的技巧,今天我要给大家分享的是如 ...

  3. 关于map 及 map 骚操作

    关于map这个东西   很冷门..................   但是,这个博客带你稍微了解一下map:   map用法:一般当作一个下表无穷大的数组   关于它的骚操作:map的鬼畜用法,可以 ...

  4. 通过HTTP的HEADER完成各种骚操作

    作为一名专业的切图工程师,我从来不care网页的header,最多关心Status Code是不是200.但是HEADER真的很重要啊,客户端从服务器端获取内容,首先就是通过HEADER进行各种沟通! ...

  5. Mac OS 上的一些骚操作

    本帖记录个人在使用 Mac 操作系统上的一些骚操作,不断更新,以飨读者. 快速移动网页到顶部或底部 用双指上下划触摸板吗?NO,我们有更骚的操作: command + ↑ 回到顶部 command + ...

  6. python骚操作---Print函数用法

    ---恢复内容开始--- python骚操作---Print函数用法 在 Python 中,print 可以打印所有变量数据,包括自定义类型. 在 3.x 中是个内置函数,并且拥有更丰富的功能. 参数 ...

  7. python20个骚操作

    Python小白需要知道的 20 个骚操作! Python 是一个解释型语言,可读性与易用性让它越来越热门.正如 Python 之禅中所述: 优美胜于丑陋,明了胜于晦涩. 在你的日常编码中,以下技巧可 ...

  8. 关于MySQL的一些骚操作——提升正确性,抠点性能

    概要 回顾以前写的项目,发现在规范的时候,还是可以做点骚操作的. 假使以后还有新的项目用到了MySQL,那么肯定是要实践一番的. 为了准备,创建测试数据表(建表语句中默认使用utf8mb4以及utf8 ...

  9. Python小白需要知道的 20 个骚操作!

    Python小白需要知道的 20 个骚操作! Python 是一个解释型语言,可读性与易用性让它越来越热门.正如 Python 之禅中所述: 优美胜于丑陋,明了胜于晦涩. 在你的日常编码中,以下技巧可 ...

  10. 一波骚操作,我把 SQL 执行效率提高了 10,000,000 倍!

    作者:风过无痕-唐 http://www.cnblogs.com/tangyanbo/p/4462734.html 场景 我用的数据库是mysql5.6,下面简单的介绍下场景 课程表: create  ...

随机推荐

  1. 基于Spring Cache实现Caffeine、jimDB多级缓存实战

    作者: 京东零售 王震 背景 在早期参与涅槃氛围标签中台项目中,前台要求接口性能999要求50ms以下,通过设计Caffeine.ehcache堆外缓存.jimDB三级缓存,利用内存.堆外.jimDB ...

  2. JAVA多线程并发编程-避坑指南

    作者:京东零售 肖朋伟 一.前言 开发过程中,多线程的应用场景可谓十分广泛,可以充分利用服务器资源,提高程序处理速度.我们通常也会使用池化技术,去避免频繁创建和销毁线程. 本篇旨在基于编码规范.工作中 ...

  3. echarts控制柱状图柱条的宽度

    barWidth属性 series: [{ name: '销量', type: 'bar', barWidth : 30,//柱图宽度 data: [5, 20, 36, 10, 10, 20] }]

  4. 【验证码逆向专栏】最新某度旋转验证码 v2 逆向分析

    声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容.敏感网址.数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 本文章未经许 ...

  5. 【JS 逆向百例】某音 X-Bogus 逆向分析,JSVMP 纯算法还原

    声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容.敏感网址.数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 本文章未经许 ...

  6. 开源IM项目OpenIM单聊及万人群压测报告

    单聊压测结论: 华为云主机s3一台:8核16G内存,网络带宽10Mb,普通磁盘(非SSD) 同时在线及压测客户端数量:1万 每秒钟发送消息量:2300条: 从发送到对方接收平均消息延时:5秒 群聊压测 ...

  7. NLP领域任务如何选择合适预训练模型以及选择合适的方案【规范建议】【ERNIE模型首选】

    1.常见NLP任务 信息抽取:从给定文本中抽取重要的信息,比如时间.地点.人物.事件.原因.结果.数字.日期.货币.专有名词等等.通俗说来,就是要了解谁在什么时候.什么原因.对谁.做了什么事.有什么结 ...

  8. 4.3 C++ Boost 日期时间操作库

    Boost 库是一个由C/C++语言的开发者创建并更新维护的开源类库,其提供了许多功能强大的程序库和工具,用于开发高质量.可移植.高效的C应用程序.Boost库可以作为标准C库的后备,通常被称为准标准 ...

  9. 基于AvaloniaUI开发跨平台.NET三维应用:环境搭建

    本文介绍在Vistual Studio 2022中使用Avalonia和集成AnyCAD AvaloniaUI三维控件的的过程. 目录 0 初始化环境 1 创建项目 2 集成AnyCAD Avalon ...

  10. 【题解】P9749 [CSP-J 2023] 公路

    \(Meaning\) \(Solution\) 这道题我来讲一个不一样的解法:\(dp\) 在写 \(dp\) 之前,我们需要明确以下几个东西:状态的表示,状态转移方程,边界条件和答案的表示. 状态 ...