如何在C#中实现Array.Copy?

我试着用ILSpy Array.Copy C#中的Array.Copy的实现,但它没有向我展示实现本身。

我写了一个简单的基准测试,Array.Copy和一个简单的for循环来复制数据。 Array.Copy更快。

如何更快地实施?

谢谢,谢伊

用于编写快速memcpy函数的相同技术:

  • 循环展开
  • 以大块(通常使用SIMD)传输对齐数据
  • CPU缓存提示(SIMD也有帮助)

也可以看看:

  • 非常快速的图像处理memcpy?
  • 如何提高memcpy的性能
  • 使用SIMD指令重写memcpy / memcmp / …是有意义的

反汇编类会让你知道这个声明:

 [MethodImpl(MethodImplOptions.InternalCall), SecurityCritical, ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)] internal static extern void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable); 

[MethodImpl]属性告诉JIT编译器该方法实际上是在CLR中实现的,用C ++而不是托管语言编写。 它查找方法名称表,并检索指向实现该方法的C ++函数的指针,并将其编译为简单的CALL指令。

获取CLR的源代码有点棘手,但SSCLI20版本对于已经存在很长时间并且不需要调整的方法非常准确。 Array.Copy()当然有资格。 我提到的表在clr \ src \ _vm \ ecall.cpp中定义,与您的问题相关的部分如下所示:

 FCFuncStart(gArrayFuncs) FCFuncElement("Copy", SystemNative::ArrayCopy) FCFuncElement("Clear", SystemNative::ArrayClear) FCFuncElement("get_Rank", Array_Rank) // etc... 

SystemNative :: ArrayCopy()函数指针将您带到clr \ src \ _vm \ comsystem.cpp。 实际的function太大了,无法复制到这里而不会让你的眼睛睁开,有很多错误检查正在进行。 它寻找一种优化副本的方法,幸运的情况是可以简单地复制数组的元素而不进行转换。 这是由名为m_memmove()的函数完成的。 您将在同一文件中找到该函数,它在32位版本的CLR中使用。

首先复制一个字节,直到目标地址在4个字节的倍数上对齐。 然后它一次复制16个字节,4次复制4次,这些复制很快,因为它们是对齐的。 然后它一次复制剩下一个字节的内容。

您现在可以看到为什么它比您自己的循环更快。 即使数组元素大小不是4字节宽,它也可以一次移动4个字节。 并且它可以在确保复制地址对齐的同时这样做,因为数组元素的物理地址是不可发现的。