C#中的快速数组副本

时间:2014-04-23 15:27:47

标签: c# arrays performance unsafe

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

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

我已经尝试过了:

1)使用UIn64和位移代替数组。 (每个元素的值也非常小。)这样可以快速复制,但会降低整个程序的速度。

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

2 个答案:

答案 0 :(得分:5)

如果您真的关心速度,我会结帐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);

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

答案 1 :(得分:0)

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

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

它们带有一些警告:

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

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

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

    public this[int index]
    {
        get => this.myIntegers[index];
        set => this.myIntegers[index] = value;
    }
}

没有内置的绑定检查,因此最好将自己包含在这样的属性中,并封装跳过方法内部绑定检查的所有功能。我正在使用移动设备,否则我会将其用于示例中。