基本的 C# 十六进制编辑器性能问题

本文关键字:编辑器 性能 问题 十六进制 | 更新日期: 2023-09-27 18:12:10

我在处理的简单十六进制编辑器的速度方面遇到问题IM 使用后台工作线程、简单的 for/foreach 循环和几个简单的语句,但它仍然比现代十六进制编辑器慢得多

这是需要很长时间才能完成的主循环

    for (int i = 0; i < buffer.Count() - 1; i++)
    {
        string hex = Convert.ToString(buffer[i], 16);
        hexstring += ((hex.Length == 1 ? hex = "0" + hex : hex = hex)) + " ";
        double x = ((double)i/(double)buffer.Count());
        bw.ReportProgress((int)(x * 100));
    }

我知道这可以写得更好一百万倍,但我很好奇是什么导致了这种延迟一个 1 MB 的可执行文件。需要 5 分钟的 +50% CPU 使用率,这远未被接受,有什么想法吗?

编辑1:缓冲区只是一个字节[],这是它的其他唯一用法

buffer = File.ReadAllBytes(((string[]) e.Data.GetData(DataFormats.FileDrop, false))[0]);

基本的 C# 十六进制编辑器性能问题

在这种情况下

,我讨厌成为"那个人",但你正在重新发明一个内置轮子。.NET 中有一个函数,可以将字节数组转换为十六进制字符串。你所需要的只是,错误这个:

string hex = BitConverter.ToString(buffer);

我想这并不能回答你为什么你的解决方案很慢的问题。由于字符串不可变性,解决方案主要运行缓慢。字符串是不可变的(只读(,当您将它们连接起来(AKA 将它们与++=运算符组合(时,您将创建一个新对象。您正在为每个循环创建 3 个,有时是 4 个字符串,这并不便宜,因为它们占用内存并且垃圾收集器最终必须收集它们。您可以通过使用 StringBuilder 来避免这种情况,该在附加字符串时在后台浮动缓冲区(与创建新字符串相比(。此外,如果buffer很大,则需要一段时间 - 有点像野兽的本性(更多的操作需要更长的时间(。希望这有帮助!

原因是您使用+=运算符来连接字符串。

每次执行此操作时,它都会将字符串的所有先前内容和添加的内容复制到新字符串中。每次都会有越来越多的数据要移动。在循环结束时,它将每次迭代移动 6 MB 的数据。

完成为 1 MB 数据创建字符串后,您将复制 3 TB 的数据。这比可用的 RAM 多一点,因此还必须进行一大堆垃圾收集来清理旧字符串并为新字符串腾出空间。

如果您改用StringBuilder,您将看到性能的巨大变化。


接下来要改进的是少一点报告进度。例如,您可以对处理的每个千字节而不是每个字节执行此操作。