根据几个测试(底部有更多测试的链接)以及我自己的一个快速而草率的测试,String.Replace 的性能优于 StringBuilder.Replace。你似乎没有遗漏任何东西。
为了完整起见,这是我的测试代码:
int big = 500;
String s;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; ++i)
{
sb.Append("cat mouse");
}
s = sb.ToString();
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < big; ++i)
{
s = s.Replace("cat", "moo");
s = s.Replace("moo", "cat");
}
sw.Stop(); Trace.WriteLine(sw.ElapsedMilliseconds); sw.Reset(); sw.Start();
for (int i = 0; i < big; ++i)
{
sb.Replace("cat", "moo");
sb.Replace("moo", "cat");
}
sw.Stop(); Trace.WriteLine(sw.ElapsedMilliseconds); sw.Reset(); sw.Start();
for (int i = 0; i < big; ++i)
{
s = s.Replace("cat", "mooo");
s = s.Replace("mooo", "cat");
}
sw.Stop(); Trace.WriteLine(sw.ElapsedMilliseconds); sw.Reset(); sw.Start();
for (int i = 0; i < big; ++i)
{
sb.Replace("cat", "mooo");
sb.Replace("mooo", "cat");
}
sw.Stop(); Trace.WriteLine(sw.ElapsedMilliseconds);
在我的机器上的输出是:
9
11
7
1977
[编辑]
我错过了一个非常重要的案例。这就是每次将字符串替换为其他内容的情况。这可能很重要,因为 C# 处理字符串的方式。下面是测试缺失案例的代码,以及我系统上的结果。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
class Program
{
static void Main()
{
var repl = GenerateRandomStrings(4, 500);
String s;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; ++i)
{
sb.Append("cat mouse");
}
s = sb.ToString();
Stopwatch sw = new Stopwatch();
sw.Start();
foreach (string str in repl)
{
s = s.Replace("cat", str);
s = s.Replace(str, "cat");
}
sw.Stop(); Trace.WriteLine(sw.ElapsedMilliseconds); sw.Reset(); sw.Start();
foreach (string str in repl)
{
sb.Replace("cat", str);
sb.Replace(str, "cat");
}
sw.Stop(); Trace.WriteLine(sw.ElapsedMilliseconds);
}
static HashSet<string> GenerateRandomStrings(int length, int amount)
{
HashSet<string> strings = new HashSet<string>();
while (strings.Count < amount)
strings.Add(RandomString(length));
return strings;
}
static Random rnd = new Random();
static string RandomString(int length)
{
StringBuilder b = new StringBuilder();
for (int i = 0; i < length; ++i)
b.Append(Convert.ToChar(rnd.Next(97, 122)));
return b.ToString();
}
}
输出:
8
1933
然而,随着我们开始增加随机字符串的长度,StringBuilder 解决方案越来越接近 String 解决方案。对于长度为 1000 个字符的随机字符串,我的结果是
138
328
在旧测试中使用这些新知识,当增加要替换的字符串的长度时,我得到了类似的结果。当替换为一千个“a”字符而不是“mooo”的字符串时,我对原始答案的结果变为:
8
11
160
326
尽管结果确实变得更接近了,但对于任何现实世界的使用,String.Replace 似乎仍然胜过 StringBuilder.Replace。