SoFunction
Updated on 2025-04-06

A brief discussion on direct data copy/conversion of various C# arrays

Before I did the Opengl program, I used the C# SharpGL library, which contains various strangely bound functions, such as the prototype:

void glInterleavedArrays(uint format, int stride, void * pointer);

The function is bound by him to:

private static extern void glInterleavedArrays(uint format, int stride, int[] pointer);

Then I was forced to learn various float[] to convert int[] to compare their efficiency (actually, I still feel that C++ is faster, a pointer type conversion, oh)

Below is a comparison of the various array assignment conversion methods and results I wrote.

, There are 2 copies of array to IntPtr, IntPtr to array [When T2 is not a type supported by Copy, there will be an error. The reason for introducing dynamic dTo is because using T2[] dTo cannot be compiled and passed], processing 2000000*100 bytes 1120.0018ms

public static T2[] Arr2Arr<T1, T2>(T1[] from)
  where T1: struct 
  where T2 :struct
{

  int byteNum =  * from[0].Sizeof();
  T2 testByte = new T2();

  dynamic dFrom = from;
  dynamic dTo = new T2[byteNum / ()];

  IntPtr ptr = (byteNum);
  (dFrom, 0, ptr, );
  (ptr, dTo, 0, );
  return dTo;
}

The method of obtaining IntPtr through pointers reduces one copy and becomes faster [when T2 is not a type supported by Copy, there will be an error. The reason for introducing pFrom is because it cannot fixed the generic T1[]].Process 2000000*100 bytes 695.9993ms

public unsafe static T2[] Arr2Arr<T1, T2>(T1[] from, void * pFrom)
  where T1 : struct
  where T2 : struct
{
  int byteNum =  * from[0].Sizeof();
  T2 testByte = new T2();
  dynamic dTo = new T2[byteNum / ()];

  IntPtr ptr = new IntPtr(pFrom);
  (ptr, dTo, 0, );
  return dTo;
}

3. Obtain IntPtr through GCHandle, and then copy [will an error occur when T2 is not a type supported by Copy].Process 2000000*100 bytes 930.0481ms

public static T2[] Arr2Arr2<T1, T2>(T1[] from)
  where T1 : struct
  where T2 : struct
{
  var gch = (from,);
  IntPtr ptr = ();

  int byteNum =  * from[0].Sizeof();
  T2 testByte = new T2();
  dynamic dTo = new T2[byteNum / ()];
  (ptr, dTo, 0, );
  ();
  return dTo;
}

method, native array copy method [without Copy, you can handle any value type],Process 2000000*100 bytes 620.042ms

public static T2[] Arr2Arr3<T1, T2>(T1[] from)
  where T1 : struct
  where T2 : struct
{
  int byteNum =  * from[0].Sizeof();
  T2 testByte = new T2();
  T2[] dTo = new T2[byteNum / ()];

  (from, dTo, );
  return dTo;
}

5. By copying the array, the fastest speed is felt like memcpy similar to c++ [without Copy, you can handle any value type],Process 2000000*100 bytes 300.0329ms

public static T2[] Arr2Arr4<T1, T2>(T1[] from)
  where T1 : struct
  where T2 : struct
{
  int byteNum =  * from[0].Sizeof();
  T2 testByte = new T2();
  T2[] dTo = new T2[byteNum / ()];

  (from, 0, dTo, 0, byteNum);

  return dTo;
}

Test some code:

byte[] from = new byte[100];
from[0] = 1;
from[1] = 1;

var last = ;
for (int i = 0; i < 2000000; i++)
{
  。。。
}
((- last).TotalMilliseconds);
//sizeof extension method internal static class ExFunc{
  public static int Sizeof(this ValueType t)
  {
    return (t);
  }
}

To sum up, it is the most applicable and efficient.

The above article briefly discusses the direct data copy/conversion of various C# arrays. This is all the content I share with you. I hope you can give you a reference and I hope you can support me more.