.net 需要优化此代码的建议

mrfwxfqh  于 2023-11-20  发布在  .NET
关注(0)|答案(3)|浏览(116)

目前,当我读取一个15Mb的文件时,我的应用程序会占用大量的内存。请注意,在主代码的末尾,我会将插入数据库的数据与文件中的原始数组进行比较。欢迎提出任何建议。
主代码:

  1. TestEntities entities = new TestEntities();
  2. using (FileStream fileStream = new FileStream(fileName + ".exe", FileMode.Open, FileAccess.Read))
  3. {
  4. byte[] bytes = new byte[fileStream.Length];
  5. int numBytesToRead = (int) fileStream.Length;
  6. int numBytesRead = 0;
  7. while (numBytesToRead > 0)
  8. {
  9. int n = fileStream.Read(bytes, numBytesRead, numBytesToRead);
  10. if (n == 0)
  11. break;
  12. numBytesRead += n;
  13. numBytesToRead -= n;
  14. }
  15. var query = bytes.Select((x, i) => new {Index = i, Value = x})
  16. .GroupBy(x => x.Index/100)
  17. .Select(x => x.Select(v => v.Value).ToList())
  18. .ToList();
  19. foreach (List<byte> list in query)
  20. {
  21. Binary binary = new Binary();
  22. binary.Name = fileName + ".exe";
  23. binary.Value = list.ToArray();
  24. entities.AddToBinaries(binary);
  25. }
  26. entities.SaveChanges();
  27. List<Binary> fileString = entities.Binaries.Where(b => b.Name == fileName + ".exe").ToList();
  28. Byte[] final = ExtractArray(fileString);
  29. if (Compare(bytes, final))
  30. {
  31. /// Some notification that was ok
  32. }
  33. }

字符串
比较方法:

  1. public bool Compare(Byte[] array1,Byte[] array2)
  2. {
  3. bool isEqual = false;
  4. if (array1.Count() == array2.Count())
  5. {
  6. for (int i = 0; i < array1.Count(); i++)
  7. {
  8. isEqual = array1[i] == array2[i];
  9. if (!isEqual)
  10. {
  11. break;
  12. }
  13. }
  14. }
  15. return isEqual;
  16. }


ExtractArray方法:

  1. public Byte[] ExtractArray(List<Binary> binaries )
  2. {
  3. List<Byte> finalArray = new List<Byte>();
  4. foreach (Binary binary in binaries)
  5. {
  6. foreach (byte b in binary.Value)
  7. {
  8. finalArray.Add(b);
  9. }
  10. }
  11. return finalArray.ToArray();
  12. }

q9yhzks0

q9yhzks01#

对于初学者,我强烈建议你投资一个分析器。这是确定为什么你的代码需要这么长时间运行或使用大量内存的正确方法。有很多分析器,包括one built into Visual Studio 2010,如果你有Premium或Ultimate。
看看谷歌或其他人的这些帖子:
What Are Some Good .NET Profilers?

Best .NET memory and performance profiler?
其次,你可能不应该假设你的应用程序不应该占用大量内存。C#应用程序(实际上,所有的.NET应用程序)都是垃圾收集的。如果我有一台有足够RAM的计算机,如果没有内存压力,没有理由运行GC,如果没有,应用程序很容易耗尽内存。对于64位环境来说尤其如此,其中进程不受32位地址空间的存储器限制。

yhived7q

yhived7q2#

在第一个两个变种comapre:

  1. bool arraysAreEqual = Enumerable.SequenceEqual(array1, array2);

字符串
或这一个

  1. public bool Compare(Byte[] array1, Byte[] array2)
  2. {
  3. if (array1.Length != array2.Length)
  4. return false;
  5. for (int i = 0; i < array1.Length; i++)
  6. {
  7. if (array1[i] != array2[i])
  8. return false;
  9. }
  10. return true;
  11. }


关于提取试试这个:

  1. foreach (Binary binary in binaries)
  2. {
  3. finalArray.AddRange(binary.Value);
  4. }

展开查看全部
mcvgt66p

mcvgt66p3#

1)你知道静态方法File.ReadAllBytes吗?它可以为你保存前15行代码。
2)我讨厌Linq.无法阅读,很难理解到底发生了什么。

  1. var query = bytes.Select((x, i) => new {Index = i, Value = x})
  2. .GroupBy(x => x.Index/100)
  3. .Select(x => x.Select(v => v.Value).ToList())
  4. .ToList();

字符串
所以对于文件的每个字节,你创建一个包含字节本身及其索引的对象。哇。如果你的文件是15mb,那就是15728640个对象。假设这个对象占用64个字节,那就是960mb的内存空间。
顺便说一句,你想干什么?

编辑

  1. var bytes = File.ReadAllBytes(filename);
  2. var chunkCount = (int)Math.Ceilling(bytes.Length / 100.0);
  3. var chunks = new List<ArraySegment<byte>>(chunkCount);
  4. for(int i = 0; i < chunkCount; i++) {
  5. chunks.Add(new ArraySegment(
  6. bytes,
  7. i * 100,
  8. Math.Min(100, bytes.Length - i * 100)
  9. ));
  10. }


这应该快几倍。
但是,为了获得更好的性能,您可以在读取文件时在数据库中插入块,而不将所有这些字节保留在内存中。

展开查看全部

相关问题