最有效的合并集合的方式,保持顺序

本文关键字:顺序 集合 有效 合并 方式 | 更新日期: 2023-09-27 18:04:41

我有3个通道:

byte[] Red;
byte[] Green;
byte[] Blue;

我需要将它们中的所有值复制到byte[Red.Length+Green.Length+Blue.Length] PA中,以便:

PA[0] = Red[0];
PA[1] = Green[0];
PA[2] = Blue[0];
PA[3] = Red[1];
/// and so on

下面是上面数组的一个例子:

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];
}

我假设要合并的集合大小相等,并且它们之间确实有一些顺序,例如[0] = Red, [1]=Green等,这些顺序必须为"合并"集合中的项保留。

C#中最有效的方法是什么?集合不一定是数组,也不一定是项字节(尽管接受字节的集合类型是可取的)。

最有效的合并集合的方式,保持顺序

我试图通过使用指针来实现更有效的方法:

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++;
    }
  }
}

在x86模式下,这大约是速度的两倍,但在x64模式下没有区别。

总之,对于大多数应用程序来说,您拥有的代码已经足够快了。如果你需要它非常快,你可以优化它一点,但不是太多。

我会尽量避免3*i乘法:

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];
}

编辑

或者类似的东西:

for (int i = 0, j = 0; i < 255; i++)
{
    PA[j++] = Red[i];
    PA[j++] = Green[i];
    PA[j++] = Blue[i];
}

(由Wiktor建议)

效率是一个薄薄的决策层,但从性能的角度来看,我想说您已经以高效的方式做了这件事。

//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];
}