C#中的快速数组副本

EM0*_*EM0 8 c# arrays performance unsafe

我有一个包含int []数组的C#类(以及其他几个字段,但数组是主要的).代码经常创建此类的副本,并且分析显示复制此数组的Array.Copy()调用需要花费大量时间.我该怎么做才能让它更快?

数组大小非常小且恒定:12个元素.理想情况下,我喜欢类似C风格的数组:类本身内部的单个内存块(不是指针).这可能在C#中吗?(如果需要,我可以使用不安全的代码.)

我已经尝试过了:

1)使用UIn64和位移代替数组.(每个元素的值也非常小.)这确实使复制速度快,但整体上减慢了程序的速度.

2)为每个数组元素使用单独的字段:int element0,int element1,int element2等.同样,当我必须访问给定索引处的元素时,这总体上较慢.

Moo*_*oop 10

我会检查System.Buffer.BlockCopy你是否真的关心速度.

http://msdn.microsoft.com/en-us/library/system.buffer.blockcopy.aspx

简单示例:

  int[] a = new int[] {1,2,3,4,5,6,7,8};
  int[] b = new int[a.Length];
  int size = sizeof(int);
  int length = a.Length * size;               
  System.Buffer.BlockCopy(a, 0, b, 0, length);
Run Code Online (Sandbox Code Playgroud)

在这里对它进行了很好的讨论:Array.Copy与Buffer.BlockCopy


Dan*_*iel 5

这篇文章很旧,但任何与 OP 处于类似情况的人都应该看看结构中的固定大小缓冲区。它们正是 OP 所要求的:直接存储在类中的具有恒定大小的原始类型数组。

您可以创建一个结构来表示您的集合,其中将包含固定大小的缓冲区。数据将直接存储在结构中,该结构将直接存储在您的类中。您可以通过简单的分配进行复制。

他们有一些警告:

  • 它们只能与原始类型一起使用。
  • 它们需要在您的结构中使用“unsafe”关键字。
  • 编译时必须知道大小。

过去,您必须使用 fixed 关键字和指针来访问它们,但最近为满足性能编程而对 C# 进行的更改使这变得不必要。您现在可以像处理数组一样使用它们。

public unsafe struct MyIntContainer
{
    private fixed int myIntegers[12];

    public int this[int index]
    {
        get => this.myIntegers[index];
        set => this.myIntegers[index] = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

没有内置的边界检查,因此最好将自己包含在这样的属性中,封装任何在方法内跳过边界检查的功能。我在移动设备上,否则我会将其应用到我的示例中。