【问题标题】:Converting array of bytes to array of shorts without copying data将字节数组转换为短裤数组而不复制数据
【发布时间】:2011-08-24 03:15:22
【问题描述】:

我有一个字节数组,实际上是来自声卡的 16 位样本。所以 1000 字节实际上代表 500 个 Short(16 位值)。

目前我正在像这样转换它们:

byte [] inputData = new byte[1000];
short [] convertedData = new short[500];
Buffer.BlockCopy(inputData, 0, convertedData , 0, 1000);

它工作正常而且速度非常快,因为它是一个低级字节副本。

但是有没有办法在没有副本的情况下做到这一点?即告诉 C# 将此内存区域视为 500 个短裤而不是 1000 个字节的数组?我知道在 C/C++ 中我可以只转换指针,它会起作用。

这个副本发生在一个紧密的循环中,每秒最多 5000 次,所以如果我可以删除这个副本,那将是值得的。

【问题讨论】:

    标签: c# memory bytearray


    【解决方案1】:

    也许 C 语言 union 的 C# analog 可以解决问题。

    【讨论】:

      【解决方案2】:
      bytes[] inputData = Array.ConvertAll<short, bytes>(bytes, delegate(short[] convertedData) { return short.Parse(convertedData); } );
      

      类似的东西,我没有检查,但也许这会帮助你:)

      【讨论】:

      • 这非常低效,因为每次调用它都会创建一个新的短数组。至少 Buffer.BlockCopy 让我重新使用相同的数组。另外,您必须组合 2 个字节才能使 1 个短。
      【解决方案3】:

      StructLayout 允许您控制类或结构中数据字段的物理布局。它通常在与需要特定布局中的数据的非托管代码交互时使用。

      试试这个:

      [StructLayout(LayoutKind.Explicit)]
      struct UnionArray
      {
          [FieldOffset(0)]
          public Byte[] Bytes;
      
          [FieldOffset(0)]
          public short[] Shorts;
      }
      
      static void Main(string[] args)
      {
          var union = new UnionArray() {Bytes = new byte[1024]};
      
          foreach (short s in union.Shorts)
          {
              Console.WriteLine(s);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-01-26
        • 1970-01-01
        • 1970-01-01
        • 2011-12-03
        • 1970-01-01
        • 2018-05-27
        • 2012-06-04
        • 2014-10-21
        • 1970-01-01
        相关资源
        最近更新 更多