I'm trying to extract all elements of a 2D array and place them into a string, so far the code completes in an average of ~950ms but I was wondering if there's any faster way of doing this.
All the buffers are 256x256 char
arrays.
for (int ii = 0; ii < 255; ii++)
{
for (int i = 0; i < 255; i++)
{
Export = Export + BufferC[i, ii];
}
}
The full context of the code snippet above. The ~950ms measurement is for the ExtractA()
function, with the other buffers taking a reasonable amount of time, but optimization would also be appreciated.
public static string ExportBuffer(int Buffer, int Line, int Dimension = 2, int Start = 0, int End = 255)
{
string Export = "Test";
for (int ii = 0; ii < 255; ii++)
{
for (int i = 0; i < 255; i++)
{
BufferC[i, ii] = 'A';
}
}
switch (Buffer)
{
default: throw new NotImplementedException("The buffer selected does not exist.");
case 00: ExtractDisplayBuffer(); break;
case 01: ExtractBufferA(); break;
case 02: ExtractBufferB(); break;
case 03: ExtractBufferC(); break;
}
void ExtractDisplayBuffer()
{
switch (Dimension)
{
case 0: ExtractX(); break;
case 1: ExtractY(); break;
case 2: ExtractA(); break;
}
void ExtractX()
{
for (int i = Start; i < End; i++)
{
Export = Export + BufferC[i, ii];
}
}
void ExtractY()
{
for (int i = Start; i < End; i++)
{
Export = Export + BufferC[i, ii];
}
}
void ExtractA()
{
for (int ii = 0; ii < 255; ii++)
{
for (int i = 0; i < 255; i++)
{
Export = Export + BufferC[i, ii];
}
}
}
}
void ExtractBufferA()
{
switch (Dimension)
{
case 0: ExtractX(); break;
case 1: ExtractY(); break;
case 2: ExtractA(); break;
}
void ExtractX()
{
for (int i = Start; i < End; i++)
{
Export = Export + BufferC[i, ii];
}
}
void ExtractY()
{
for (int i = Start; i < End; i++)
{
Export = Export + BufferC[i, ii];
}
}
void ExtractA()
{
for (int ii = 0; ii < 255; ii++)
{
for (int i = 0; i < 255; i++)
{
Export = Export + BufferC[i, ii];
}
}
}
}
void ExtractBufferB()
{
switch (Dimension)
{
case 0: ExtractX(); break;
case 1: ExtractY(); break;
case 2: ExtractA(); break;
}
void ExtractX()
{
for (int i = Start; i < End; i++)
{
Export = Export + BufferC[i, ii];
}
}
void ExtractY()
{
for (int i = Start; i < End; i++)
{
Export = Export + BufferC[i, ii];
}
}
void ExtractA()
{
for (int ii = 0; ii < 255; ii++)
{
for (int i = 0; i < 255; i++)
{
Export = Export + BufferC[i, ii];
}
}
}
}
void ExtractBufferC()
{
switch (Dimension)
{
case 0: ExtractX(); break;
case 1: ExtractY(); break;
case 2: ExtractA(); break;
}
void ExtractX()
{
for (int i = Start; i < End; i++)
{
Export = Export + BufferC[i, ii];
}
}
void ExtractY()
{
for (int i = Start; i < End; i++)
{
Export = Export + BufferC[i, ii];
}
}
void ExtractA()
{
for (int ii = 0; ii < 255; ii++)
{
for (int i = 0; i < 255; i++)
{
Export = Export + BufferC[i, ii];
}
}
}
}
return Export;
}
You can use MemoryMarshal.CreateSpan()
to create a ReadOnlySpan<char>
from a 2D char array, and then you can pass that span to the string
constructor.
I think this will be one of the more performant approaches:
var buffer = new char[256, 256];
for (int i = 0; i < 256; i++)
{
for (int j = 0; j < 256; j++) // Fill with some arbitrary daya.
{
buffer[i, j] = (char)('A' + (i * 256 + j) % 64);
}
}
// Create the span.
var span = MemoryMarshal.CreateSpan(
ref Unsafe.As<byte, char>(ref MemoryMarshal.GetArrayDataReference(buffer)),
buffer.Length);
// Create the string from the span.
string s = new string(span);
// Show that the string contains the correct data.
Console.WriteLine(s);
Note that creating a span in the code above does NOT copy any data. However, the data will be copied once in the call to new string(span)
, but the implementation uses a very fast copy.
You might like to write a separate method to convert 2D arrays of any type to make the code more readable:
public static ReadOnlySpan<T> TwoDimensionalArrayAsSpan<T>(T[,] array)
{
return MemoryMarshal.CreateSpan(
ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array)),
array.Length);
}
Then creating the span would look like:
// Create the span.
var span = TwoDimensionalArrayAsSpan(buffer);