C#用随机数据填充结构数组

C#用随机数据填充结构数组,c#,random,struct,C#,Random,Struct,出于测试目的,我想做以下事情: class ArrayOfStructWithRandomData<T> where T : struct { private T[] array; ArrayOfStructWithRandomData() { array = new T[1000000]; InitializeArrayToRandomData(); } } 有更好的方法吗?我不确定这是否是您要搜索的,但您可以在结构中使用隐式运算符来初始化它,就像下

出于测试目的,我想做以下事情:

class ArrayOfStructWithRandomData<T> where T : struct {
  private T[] array;

  ArrayOfStructWithRandomData() {
    array = new T[1000000];
    InitializeArrayToRandomData();
  }
}

有更好的方法吗?

我不确定这是否是您要搜索的,但您可以在结构中使用隐式运算符来初始化它,就像下面的示例:

public static implicit operator MyStruct(T[] value) {
    return new MyStruct() { structValue = value, Structlength = value.Length };
  }

我不确定这是否是您正在搜索的内容,但您可以在结构中使用隐式运算符对其进行初始化,就像下面的示例:

public static implicit operator MyStruct(T[] value) {
    return new MyStruct() { structValue = value, Structlength = value.Length };
  }

如果要关闭特定方法或属性的优化,可以使用

[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]

这将防止编译器和稍后的抖动优化或内联该方法。然后,您就可以继续使用默认值,而无需编译器最终对其进行优化。

如果您想关闭对特定方法或属性的优化,您可以使用它

[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
这将防止编译器和稍后的抖动优化或内联该方法。然后,您就可以继续使用默认值,而无需编译器最终进行优化。

这样如何:

        [StructLayout(LayoutKind.Sequential)]
        struct Root
        {
            [MarshalAs(UnmanagedType.Struct, SizeConst = 1000000)]
            Child[] children { get; set; }
        }
        struct Child
        {
            int property1 { get; set; }
            int property2 { get; set; }
            int property3 { get; set; }
            int property4 { get; set; }
            int property5 { get; set; }
            int property6 { get; set; }
        }
这个怎么样:

        [StructLayout(LayoutKind.Sequential)]
        struct Root
        {
            [MarshalAs(UnmanagedType.Struct, SizeConst = 1000000)]
            Child[] children { get; set; }
        }
        struct Child
        {
            int property1 { get; set; }
            int property2 { get; set; }
            int property3 { get; set; }
            int property4 { get; set; }
            int property5 { get; set; }
            int property6 { get; set; }
        }

如果希望从非托管内存复制到托管阵列中,最有效的方法是固定阵列并使用
marshall.copy
进行复制

void BlitFromByteArrayToArray(byte[] src, T[] dst)
{
    Debug.Assert(src.Length == dst.Length * Marshal.SizeOf(typeof(T)));

    GCHandle handle = GCHandle.Alloc(dst, GCHandleType.Pinned);
    try
    {
        Marshal.Copy(src, 0, handle.AddrOfPinnedObject(), src.Length);
    }
    finally
    {
        handle.Free();
    }
}
请注意,我没有分配非托管内存,然后用随机数据填充该非托管内存,而是用字节数组来保存源随机数据。没有必要为此使用非托管内存

请注意,整个方法都假定
T
是一种可空降类型

最后,如果效率很重要,最好采取以下措施:

  • 分配托管阵列
  • 使用
    GCHandle.Alloc
    锁定阵列
  • 将随机数据写入由
    AddrOfPinnedObject
    返回的非托管数组
  • 取消绑定数组

  • 这样可以避免先写入一个缓冲区,然后再复制到另一个缓冲区。

    如果要将非托管内存复制到托管阵列中,最有效的方法是固定阵列,然后使用
    封送。复制

    void BlitFromByteArrayToArray(byte[] src, T[] dst)
    {
        Debug.Assert(src.Length == dst.Length * Marshal.SizeOf(typeof(T)));
    
        GCHandle handle = GCHandle.Alloc(dst, GCHandleType.Pinned);
        try
        {
            Marshal.Copy(src, 0, handle.AddrOfPinnedObject(), src.Length);
        }
        finally
        {
            handle.Free();
        }
    }
    
    请注意,我没有分配非托管内存,然后用随机数据填充该非托管内存,而是用字节数组来保存源随机数据。没有必要为此使用非托管内存

    请注意,整个方法都假定
    T
    是一种可空降类型

    最后,如果效率很重要,最好采取以下措施:

  • 分配托管阵列
  • 使用
    GCHandle.Alloc
    锁定阵列
  • 将随机数据写入由
    AddrOfPinnedObject
    返回的非托管数组
  • 取消绑定数组


  • 这样可以避免先写入一个缓冲区,然后再复制到另一个缓冲区。

    目的是什么?什么类型的测试要求您创建可能无效的对象?可能是使用反射您可以检索
    T
    的字段并用随机值填充它们。在性能测试中,我不希望编译器优化这些内容,因为它看到所有结构都默认初始化。例如,我喜欢使用此实例中的封送处理方法。我不确定PtrToStructure为什么在for循环中。问题是,您所做的任何事情都是不安全的,因为无法通过泛型表示
    struct
    只能包含
    struct
    成员。第一次使用包含引用的
    struct
    调用此方法,并将该引用初始化为随机值时,欢闹会随之而来。目的是什么?什么类型的测试要求您创建可能无效的对象?可能是使用反射您可以检索
    T
    的字段并用随机值填充它们。在性能测试中,我不希望编译器优化这些内容,因为它看到所有结构都默认初始化。例如,我喜欢使用此实例中的封送处理方法。我不确定PtrToStructure为什么在for循环中。问题是,您所做的任何事情都是不安全的,因为无法通过泛型表示
    struct
    只能包含
    struct
    成员。第一次使用包含引用的
    struct
    调用此方法并将该引用初始化为随机值时,hilarity将随之出现。问题是,我仍然需要优化(因为它是性能测试)。但我不希望任何优化基于我的所有结构内容都是默认初始化的这一事实。问题是,我仍然需要优化(因为它是性能测试)。但我不希望任何优化基于我的所有结构内容都是默认初始化的这一事实。这如何用随机数据填充数组?这不是用随机数据填充,因为发布的代码没有这样做。它是关于将数据从非托管移动到托管。我只是建议消除发布代码中的for循环。正确的方法是使用
    GCHandle.Alloc固定数组(arr,GCHandleType.pinted
    然后
    AddrOfPinnedObject
    然后
    Marshal.Copy
    。这是如何用随机数据填充数组的?这不是用随机数据填充,因为发布的代码没有这样做。这是关于将数据从非托管移动到托管。我只是建议在正确的方法是使用
    GCHandle.Alloc锁定数组(arr,GCHandleType.pinted
    然后
    AddrOfPinnedObject
    然后
    Marshal.Copy
    。David:不是封送。Alloc将结构放入非托管内存吗?pin所做的就是阻止垃圾收集处理内存。@jdweng这里没有
    封送。Alloc
    确定,但它仍然是非托管的:GCHandle Pr提供了一种从非托管内存访问托管对象的方法。@jdweng固定不会使内存成为非托管内存。它只是阻止GC移动内存()。