Reputation: 786
I have 3 channels:
byte[] Red;
byte[] Green;
byte[] Blue;
I need to copy all the values from them into a byte[Red.Length+Green.Length+Blue.Length] PA
, so that:
PA[0] = Red[0];
PA[1] = Green[0];
PA[2] = Blue[0];
PA[3] = Red[1];
/// and so on
Here is an example with the above arrays:
byte[] Red = new byte[255];
byte[] Green = new byte[255];
byte[] Blue = new byte[255];
byte[] PA = new byte[Red.Length + Green.Length + Blue.Length];
for (int i = 0; i != 255; ++i)
{
PA[i*3 + 0] = Red[i];
PA[i*3 + 1] = Green[i];
PA[i*3 + 2] = Blue[i];
}
I'm assuming that the collections to be merged are of equal sizes and that they do have some order amongst themselves e.g. [0] = Red
, [1]=Green
, etc. that has to be preserved for the items in the "merged" collection.
What is the most efficient way to do this in C#
? The collections do not have to be arrays nor the items bytes (although collection types that accept bytes would be appreciated).
Upvotes: 3
Views: 254
Reputation: 700552
I tried to make a more efficent way by using pointers:
unsafe {
fixed (byte* red = Red, green = Green, blue = Blue, pa = PA2) {
byte* r = red, g = green, b = blue, p = pa;
for (int i = 0; i < 255; i++) {
*p = *r; p++; r++;
*p = *g; p++; g++;
*p = *b; p++; b++;
}
}
}
In x86 mode this is about twice as fast, but in x64 mode there is no difference.
In conclusion, the code that you have is already fast enough for most applications. If you need it to be really fast you can optimise it a bit, but not much.
Upvotes: 5
Reputation: 125640
I would try avoiding 3*i
multiplication:
byte[] Red = new byte[255];
byte[] Green = new byte[255];
byte[] Blue = new byte[255];
int newSize = Red.Length + Green.Length + Blue.Length;
byte[] PA = new byte[newSize];
for (int i = 0; i < newSize; i += 3)
{
PA[i + 0] = Red[i];
PA[i + 1] = Green[i];
PA[i + 2] = Blue[i];
}
Edit
Or even something like that:
for (int i = 0, j = 0; i < 255; i++)
{
PA[j++] = Red[i];
PA[j++] = Green[i];
PA[j++] = Blue[i];
}
(Suggested by Wiktor)
Upvotes: 5
Reputation: 62276
Efficiency is a thin decisional layer, but from the performance perspective, I would say that you already do it in efficient way.
//allocate immediately memory need, so more shrinking of memory will happen
byte[] PA = new byte[Red.Length + Green.Length + Blue.Length];
//use for loop, that normally equals to foreach in some cases is faster
for (int i = 0; i != 255; ++i)
{
PA[i + 0] = Red[i];
PA[i + 1] = Green[i];
PA[i + 2] = Blue[i];
}
Upvotes: 2