列表<byte> 的性能问题

Tob*_*toe 0 .net c# performance byte list

我有一个文件(~30MB),我用 File.ReadAllBytes() 读取该文件,该文件有很多不同长度的结构化数据(中间没有终止符)。所以我必须检查第一个数据的长度,将其剪掉并继续下一个数据,依此类推。因此,将其拆分为不同的任务是不可能的。

还有其他方法可以加快这个速度吗?(目前大约需要20分钟)

    List<Record> Records = new List<Record>  
    internal static void Import(List<byte> filedata)
    {
        var task = Task.Run(() =>
        {
            while (filedata.Count > 0)
            {
                Record record = new Record()
                filedata = record.GetData(filedata);
                Records.Add(record)
            }
        });
    }
      
    //inside class "Record"
    internal List<byte> GetData(List<byte> filedata)
    {
        this.length = BitConverter.ToUInt32(new byte[4] { filedata[8], filedata[9], filedata[10], filedata[11] }, 0);
        this.data = new byte[this.length + 1];
        filedata.CopyTo(0, this.data, 0, this.length);
        filedata.RemoveRange(0, 16 + this.length);
        return filedata;
    }
Run Code Online (Sandbox Code Playgroud)

Bli*_*ndy 5

我认为,问题不在于如何让事情变得更好,而在于如何让事情变得更糟。这里存在一些严重的算法和框架误解,以至于我建议对写这篇文章的人进行再教育。

具体细节:

  • 不要只是为了从字节缓冲区中提取数字而分配数组,您可以使用四年级数学手动写出它,或者使用像MemoryMarshal.Cast这样的内置函数重新解释到位的字节。
  • 您不应该从主数组中返回数据数组(实际上是一个列表!!),您应该只提取您实际需要的数据并将其返回到struct. 如果出于某种原因您确实无法做到这一点,那么您可以使用跨度并ArraySegment避免无缘无故地分配新列表和复制数据。
  • filedata.RemoveRange(0, 16 + this.length);现在这个人只是非常懒惰。从数组(实际上又是列表)的开头删除项目是一个线性操作,只需保留最后处理的字节的索引并在处理数据时将其向前移动即可。

  • 嗯,我也会添加这一点,但他只是在事后评论中提到了他如何获得缓冲区。 (2认同)