Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基本C#十六进制编辑器性能问题_C#_String_Performance - Fatal编程技术网

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

基本C#十六进制编辑器性能问题,c#,string,performance,C#,String,Performance,我有一个简单的十六进制编辑器我的工作速度问题 我使用了一个后台工作程序,简单的for/foreach循环和几个简单的语句,但它仍然比现代十六进制编辑器慢很多 这是一个主循环,需要很长时间才能完成 for (int i = 0; i < buffer.Count() - 1; i++) { string hex = Convert.ToString(buffer[i], 16); hexstring += ((hex.Length == 1 ?

我有一个简单的十六进制编辑器我的工作速度问题 我使用了一个后台工作程序,简单的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));
    }

原因是您使用了
+=
操作符来连接字符串

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

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

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


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

在这种情况下,我不想成为“那个家伙”,但您正在重新发明一个内置轮子。NET中有一个函数,可以将字节数组转换为十六进制字符串。你所需要的只是爱,错误在于:

string hex = BitConverter.ToString(buffer);

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

a)使用StringBuilder。b)不要调用<代码> RePrimePosivs/COD>太多。你不需要为每个字节调用<代码> BW。RePrimePosip>代码(除非你的数据小于100字节):真的,考虑<代码>(I %(Buff.Calp/ 100)=0)BW。ReavePrimest.,它将报告每一个百分比。(将为真~100次,具体取决于
buffer.Count
被100整除的程度)“为什么循环中的字符串串联很慢”已经在许多现有问题中得到了解决。Nice(+1)这里的答案还解决了代码中的其他问题。我建议在发布新问题时尽量减少最重要部分的示例代码。即,在这种情况下,您应该将字符串相关代码和通知相关代码拆分为两个单独的示例,并在需要时问两个问题(可以帮助您自己找到现有的副本).不仅如此,还有
“0”+hex
串联。@DaveHaney:相比之下,这是非常便宜的,因为这只是一个O(n)操作。对16个十六进制数字中的9个进行双倍的字符串创建,不是吗?@DaveHaney:是的,但它只是非常短的字符串。在循环结束时,代码每次迭代都会复制6MB的数据,因此与此相比,另一个小字符串可以忽略不计。
string hex = BitConverter.ToString(buffer);