加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – Performance Byte []到Generic

发布时间:2020-12-15 23:26:50 所属栏目:百科 来源:网络整理
导读:我需要制作一个字节[] – T扩展方法,需要它快速(不需要它漂亮) 在绝对性能关键环境中,此功能将在很短的时间内被称为100次100次. 我们目前正在优化“滴答”级别,每个刻度转换为在callstack中高出几毫秒,因此需要原始速度而不是可维护性(不是我喜欢设计软件,但
我需要制作一个字节[] – > T扩展方法,需要它快速(不需要它漂亮)

在绝对性能关键环境中,此功能将在很短的时间内被称为100次100次.

我们目前正在优化“滴答”级别,每个刻度转换为在callstack中高出几毫秒,因此需要原始速度而不是可维护性(不是我喜欢设计软件,但其背后的推理超出了范围) .

考虑下面的代码,它是干净和可维护的,但它相对较慢(可能是由于装箱和拆箱),这可以优化为更快?

public static T ConvertTo<T>(this byte[] bytes,int offset = 0)
{
    var type = typeof(T);
    if (type == typeof(sbyte)) return bytes[offset].As<T>();
    if (type == typeof(byte)) return bytes[offset].As<T>();
    if (type == typeof(short)) return BitConverter.ToInt16(bytes,offset).As<T>();
    if (type == typeof(ushort)) return BitConverter.ToUInt32(bytes,offset).As<T>();
    if (type == typeof(int)) return BitConverter.ToInt32(bytes,offset).As<T>();
    if (type == typeof(uint)) return BitConverter.ToUInt32(bytes,offset).As<T>();
    if (type == typeof(long)) return BitConverter.ToInt64(bytes,offset).As<T>();
    if (type == typeof(ulong)) return BitConverter.ToUInt64(bytes,offset).As<T>();

    throw new NotImplementedException();
}

public static T As<T>(this object o)
{
    return (T)o;
}

解决方法

我也需要这个,我发现使用指针和不安全的代码可以更快地完成对这些原始类型的转换.喜欢:

public unsafe int ToInt(byte[] bytes,int offset)
{
    fixed(byte* ptr = bytes)
    {
         return *(int*)(ptr + offset);
    }
}

但遗憾的是C#不支持泛型指针类型,所以我不得不在IL中编写这段代码,而不关心泛型约束:

.method public hidebysig static !!T  Read<T>(void* ptr) cil managed
{
    .maxstack  8
    nop         
    ldarg.0     
    ldobj !!T
    ret 
}

它不漂亮,但它似乎适用于我的情况.使用此方法时要小心 – 您可以将任何类型作为参数传递,但我不知道它会做什么.

您可以在github找到整个il文件
或者下载已编译的程序集https://github.com/exyi/RaptorDB-Document/blob/master/GenericPointerHelpers/GenericPointerHelpers.dll?raw=true我在那里有更多的帮助程序.

编辑:我忘了写如何使用这种方法.假设你已经像我一样在GenericPointerHelper类中编译了这个方法,你可以实现类似于我的ToInt的ConvertTo方法:

public unsafe T ConvertTo<T>(byte[] bytes,int offset)
    where T: struct // not needed to work,just to eliminate some errors
{
    fixed(byte* ptr = bytes)
    {
         return GenericPointerHelper.Read<T>(ptr + offset);
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读