用字符串替换字符(0x10)(优化方式)

时间:2016-11-29 04:44:46

标签: c# string performance

这是一个常见的问题,但我希望这不会被标记为重复,因为问题的性质不同(请不要只读标题)

不知道String.Replace的存在我写了以下内容:

int theIndex = 0;

while ((theIndex = message.IndexOf(separationChar, theIndex)) != -1) //we found the character
{
    theIndex++;
    if (theIndex < message.Length)//not in the last position 
    {
        message = message.Insert(theIndex, theTime);
    }
    else 
    {
        // I dont' think this is really neccessary
        break;
    }

} //while finding characters

正如您所看到的,我正在使用名为“theTime”的字符串替换消息String中出现的separationChar。

现在,这适用于小字符串,但我已经获得了一个非常庞大的字符串(大约几百字节的顺序 - 顺便说一下,String或StringBuilder有限制吗?)并且需要花费很多时间...

所以我的问题是:

1)如果我这样做是否更有效率

oldString=separationChar.ToString();
newString=oldString.Insert(theTime);

message= message.Replace(oldString,newString);

2)当以非常快速有效的方式找到一些char 时,还有其他方法可以处理非常长的字符串以插入字符串(theTime)吗?

非常感谢

2 个答案:

答案 0 :(得分:0)

正如Danny已经提到的,string.Insert()实际上每次使用它时都会创建一个 new 实例,而且这些实例在某些时候也必须进行垃圾回收。

您可以从空StringBuilder开始构造结果字符串:

public static string Replace(this string str, char find, string replacement)
{
    StringBuilder result = new StringBuilder(str.Length); // initial capacity
    int pointer = 0;
    int index;
    while ((index = str.IndexOf(find, pointer)) >= 0)
    {
        // Append the unprocessed data up to the character
        result.Append(str, pointer, index - pointer);
        // Append the replacement string
        result.Append(replacement);
        // Next unprocessed data starts after the character
        pointer = index + 1;
    }

    // Append the remainder of the unprocessed data
    result.Append(str, pointer, str.Length - pointer);
    return result.ToString();
}

这不会导致为每次出现的角色创建新的string(并收集垃圾)。相反,当StringBuilder的内部缓冲区已满时,它将创建一个具有足够容量的新缓冲区块#34;当缓冲区已满时,从reference source引用:

  

计算我们需要的新块的长度

     

我们使新块至少足以满足当前需求(minBlockCharCount),但也与当前长度一样大(从而使容量增加一倍),达到最大值   (所以我们留在小对象堆中,即使是,也永远不会分配很大的块   字符串变得非常大)。

答案 1 :(得分:0)

感谢您回答我的问题。 我正在写一个答案,因为我必须报告我在我的问题中尝试了解决方案1)并且根据我的程序结果确实更有效。 String.Replace可以非常快速地将字符串(来自char)替换为另一个字符串。

{
      "Comment": "Update the A record set",
      "Changes": [
        {
          "Action": "UPSERT",
          "ResourceRecordSet": {
            "Name": "mydomain.com",
            "Type": "A",
            "TTL": 300,
            "ResourceRecords": [
              {
                "Value": "4.4.4.4"
              }
            ]
          }
        }
      ]
    }