gpt4 book ai didi

c# - 检查类型是否可 blittable 的最快方法?

转载 作者:可可西里 更新时间:2023-11-01 03:09:50 26 4
gpt4 key购买 nike

在我的序列化器/反序列化器中,我有以下片段:

    if (element_type.IsValueType && collection_type.IsArray)
{
try
{
GCHandle h = GCHandle.Alloc(array_object, GCHandleType.Pinned);
int arrayDataSize = Marshal.SizeOf(element_type) * c.Count;
var array_data = new byte[arrayDataSize];
Marshal.Copy(h.AddrOfPinnedObject(), array_data, 0, arrayDataSize);
h.Free();
WriteByteArray(array_data);

return;
}
catch (ArgumentException)
{
//if the value type is not blittable, then we need to serialise each array item one at a time
}
}

其目的是尝试以最有效的方式(即,仅将内容作为一堆字节)将值类型数组写入流。

当类型是值类型但不可 blittable 并且 Alloc() 失败时,问题就来了。此刻,异常被捕获并将控制权传递给处理数组的代码,就好像它由引用类型组成。

然而,由于在我的应用程序中遇到的值类型的数量,此检查(由于异常的抛出和捕获非常慢)被证明是一个严重的瓶颈。所以我想知道,检查类型是否可 blittable 的最快方法是什么?

最佳答案

当前的答案适用于提问者的情况,但根据规范,可 blittable 值类型的数组本身也是可 blittable 类型。稍微扩展了 Ondřej 的方法,因此它考虑到了这一点,并且也适用于引用类型:

public static bool IsBlittable<T>()
{
return IsBlittableCache<T>.Value;
}

public static bool IsBlittable(Type type)
{
if(type.IsArray)
{
var elem = type.GetElementType();
return elem.IsValueType && IsBlittable(elem);
}
try{
object instance = FormatterServices.GetUninitializedObject(type);
GCHandle.Alloc(instance, GCHandleType.Pinned).Free();
return true;
}catch{
return false;
}
}

private static class IsBlittableCache<T>
{
public static readonly bool Value = IsBlittable(typeof(T));
}

作为副作用,这会为 string 返回(尽管是正确的)false,因为 GetUninitializedObject 无法创建它。假设 Alloc 确实检查了 blittability(string 除外),这应该是可靠的。

关于c# - 检查类型是否可 blittable 的最快方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10574645/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com