一尘不染

String.Replace .NET Framework的内存效率和性能

c#

 string str1 = "12345ABC...\\...ABC100000"; 
 // Hypothetically huge string of 100000 + Unicode Chars
 str1 = str1.Replace("1", string.Empty);
 str1 = str1.Replace("22", string.Empty);
 str1 = str1.Replace("656", string.Empty);
 str1 = str1.Replace("77ABC", string.Empty);

 // ...  this replace anti-pattern might happen with upto 50 consecutive lines of code.

 str1 = str1.Replace("ABCDEFGHIJD", string.Empty);

我继承了一些与上述代码段相同的代码。它需要一个巨大的字符串,并从大字符串中替换(删除)恒定的较小字符串。

我相信这是一个非常耗费内存的过程,因为每次替换都会在内存中分配新的大的不可变字符串,等待通过GC终止。

1.忽略内存问题,替换这些值的最快方法是什么?

2.实现相同结果的最有效内存方式是什么?

我希望这些是相同的答案!

介于这些目标之间的实用解决方案也受到赞赏。

假设:

  • 所有替换都是不变的,并且事先知道
  • 底层字符确实包含一些Unicode [non-ascii]字符

阅读 531

收藏
2020-05-19

共1个答案

一尘不染

__.NET字符串中的 所有 字符均为“ unicode字符”。您是不是说他们不是ascii?这应该不成问题-除非您遇到构图问题,例如在尝试替换“
e急性”时未替换“ e +急性重音”。

您可以尝试使用带有Regex.Replace或的正则表达式StringBuilder.Replace。下面的示例代码对两者都做同样的事情:

using System;
using System.Text;
using System.Text.RegularExpressions;

class Test
{
    static void Main(string[] args)
    {
        string original = "abcdefghijkl";

        Regex regex = new Regex("a|c|e|g|i|k", RegexOptions.Compiled);

        string removedByRegex = regex.Replace(original, "");
        string removedByStringBuilder = new StringBuilder(original)
            .Replace("a", "")
            .Replace("c", "")
            .Replace("e", "")
            .Replace("g", "")
            .Replace("i", "")
            .Replace("k", "")
            .ToString();

        Console.WriteLine(removedByRegex);
        Console.WriteLine(removedByStringBuilder);
    }
}

我不想猜测哪种效率更高-
您必须使用特定的应用程序进行基准测试。regex方法可能一次就能完成所有操作,但是与StringBuilder中的许多替换操作相比,该过程将占用大量CPU。

2020-05-19