将int []转换为short [],反之亦然

时间:2016-04-25 13:54:32

标签: c# kinect kinect-sdk

我正在尝试使用Kinect for Xbox 360和SDK 1.8来计算播放器的表面积。我遇到了一个小小的打嗝,我需要将short[]转换为int[],反之亦然。解释更多...

        short[] rawDepthData = new short[depthFrame.PixelDataLength];
        depthFrame.CopyPixelDataTo(rawDepthData);

但我需要rawDepthData格式的int[] ..

帮助表示感谢 非常感谢

2 个答案:

答案 0 :(得分:4)

对于您可能希望尽可能快的内容,您可能需要考虑编写自己的循环以将short[]数组复制到新的int[]数组中,例如:

public static int[] Convert(short[] input)
{
    int[] result = new int[input.Length];

    for (int i = 0; i < input.Length; ++i)
        result[i] = input[i];

    return result;
}

以下是您如何转换回来的。重要提示:这假定int值均适合short。如果他们不这样做,他们将被截断,价值观会发生变化!

public static short[] Convert(int[] input)
{
    short[] result = new short[input.Length];

    unchecked
    {
        for (int i = 0; i < input.Length; ++i)
            result[i] = (short) input[i];
    }

    return result;
}

(注意:将此性能与Array.ConvertAll()的性能进行比较时,必须将此代码编译为RELEASE构建 - 否则您将比较调试版本与版本构建。)

答案 1 :(得分:2)

您可以使用Linq:

var myIntData = rawDepthData.Select(x => (int)x).ToArray();

或者只是一个for循环(这会更快),如果你的目标是性能:

var myIntData = new int[rawDepthData.Length];
for(var i = 0; i < rawDepthData.Length; i++)
   myIntData[i] = rawDepthData[i];

如果努力提高性能,我会使用for方法,并且还准备好int[]数组(并且每次都不会分配一个新数组),因为原始深度数据长度更有可能不改变

另一种更高效的方法是使用unsafe,指针并展开循环:

unsafe static void CopyData(short[] input, int[] output)
{
    fixed(short* pt1 = input)
    fixed(int* pt2 = output)
    {
        short* pt1f = pt1;
        int* pt2f = pt2;
        for (int i = 0; i < input.Length/8; i ++)
        {
            *pt2f = *pt1f;
            *(pt2f + 1) = *(pt1f + 1);
            *(pt2f + 2) = *(pt1f + 2);
            *(pt2f + 3) = *(pt1f + 3);
            *(pt2f + 4) = *(pt1f + 4);
            *(pt2f + 5) = *(pt1f + 5);
            *(pt2f + 6) = *(pt1f + 6);
            *(pt2f + 7) = *(pt1f + 7);
            pt1f += 8;
            pt2f += 8;
        }
    }
}

虽然.NET框架有点难看,但这应该是最快的方法。我实际上做了一些分析(不是任何科学),在我的一些测试中,使用不同的数组大小和循环,unsafe一个增加了约30-40%(注意没有展开循环,我获得了非常微小的性能提升约5-10%,具体取决于数组大小)...这实际上假设长度可被8整除,您可以根据需要进行调整或检查: - )

仿形

*只是因为我很好奇并且现在有点时间

由于我很好奇,这是我对不同方法的一些评价结果(100%是最快的方法,“迭代”是我进行复制操作的次数...我验证了数据,但那是在性能计算之外),数组也是预先分配的(不是在每次迭代时分配)。我离开了Linq因为速度慢了。

  1. 100,000次迭代,数组长度为80,000
  2.   

    不安全展开:100% - 00:00:02.5536184

         

    简单的()循环:70,88% - 00:00:03.6024272

         

    foreach(...):59,24% - 00:00:04.3105598

         

    展开():38,26% - 00:00:06.6739715

    1. 1,000,000次迭代,数组长度为8,000
    2.   

      不安全展开:100% - 00:00:02.3733392

           

      简单的()循环:67,70% - 00:00:03.5055304

           

      foreach(...):55,00% - 00:00:04.3149544

           

      展开():39,53% - 00:00:06.0041744

      1. 10,000次迭代,阵列长度为800,000
      2.   

        不安全展开:100% - 00:00:02.5565005

             

        简单的()循环:73,69% - 00:00:03.4688333

             

        foreach(...):59,75% - 00:00:04.2783304

             

        展开():39,46% - 00:00:06.4778782

        我真的很惊讶安全的“展开”for是最昂贵的方法......考虑一下,这很有道理,但乍一看(至少对我来说,来自x86)汇编背景,其中展开性能的循环在那些日子里很常见)我从来没有这么说过。我也不希望foreach比简单的for慢得多。