性能:char vs string

6

只是出于好奇(并不指望有显著结果),在性能方面以下哪个代码更好呢?

private void ReplaceChar(ref string replaceMe) {
  if (replaceMe.Contains('a')) {
    replaceMe=replaceMe.Replace('a', 'b');
  }
}

private void ReplaceString(ref string replaceMe) {
  if (replaceMe.Contains("a")) {
    replaceMe=replaceMe.Replace("a", "b");
  }
}

在第一个示例中,我使用了char,在第二个示例中使用了Contains()和Replace()中的字符串。
第一个示例因为使用了更加节省内存的"char",所以性能更好吗?还是第二个示例更好,因为编译器在此操作中不需要强制转换?
或者这全部都是无稽之谈,因为CLR在两种变化中生成相同的代码?

我认为重新创建字符串比实际替换更糟糕。 - Patrick Hofman
2
只是猜测,但char版本应该表现更好:无需分配字符串,查找单个字符比查找一组字符(即字符串)更容易, Replace实现提前知道返回的字符串大小,因此无需进行潜在的额外分配... 但想要知道确切情况就必须进行测量。 - Zdeslav Vojkovic
if语句中的Contains()是否是不必要的?Replace()已经会检查它是否包含了。 - Johan
自己编写一个比较循环真的那么难吗? - Peter B
1
@PeterB 是的,在.NET中使用字符串参数编写高效的比较/替换代码并不容易,如果框架已经有一个好的实现,为什么还会有人这样做呢? - Zdeslav Vojkovic
@PeterB,正如我在Dmitris的回答中所写的那样:我并没有期望获得超出正常分布的显着差异。 - Ole Albers
2个回答

12

如果你有两匹马,想知道哪一个更快...

  String replaceMe = new String('a', 10000000) + 
                     new String('b', 10000000) + 
                     new String('a', 10000000);

  Stopwatch sw = new Stopwatch();

  sw.Start();

  // String replacement 
  if (replaceMe.Contains("a")) {
    replaceMe = replaceMe.Replace("a", "b");
  }

  // Char replacement
  //if (replaceMe.Contains('a')) {
  //  replaceMe = replaceMe.Replace('a', 'b');
  //}

  sw.Stop();

  Console.Write(sw.ElapsedMilliseconds);

我的电脑配置是Core i5 3.2GHz, 64位, .Net 4.6,Char 替换只需要 60 毫秒,而 String 替换需要500 毫秒。

 replaceMe = replaceMe.Replace('a', 'b')

是关于快了约9倍


说实话,我没有进行测量,因为我预计差异应该在千分之一的区域内。很高兴知道确实有可测量的差异。顺便说一句:让两匹马跑100万次通常会导致两匹马都死亡 :) - Ole Albers
值得注意的是,我们正在处理一个长度为3000万个字符的字符串,而“慢速”版本仍然只需要不到一秒钟的时间。除非您已经确定并且有确凿的证据表明这是应用程序的瓶颈,否则不要过多地解读此类测量结果。对于大多数可想象的应用程序来说,两者都比“足够快”要快得多。 - sara
1
@kai:你说得很对,但问题是以“只是出于好奇…”开头的,我希望好奇心得到满足 ;) - Dmitry Bychenko
当然,我也会对这样的东西感到非常好奇,但我想强调的是,在大多数情况下,答案只是一个好奇心,实际价值很小。不过,在问题的范围内,我认为这是一个很好的回答! - sara

1
我们无法确定代码是否替换成功,因为大多数替换是在CLR内部完成的,并且进行了大量优化。
我们可以说的是:替换一个字符具有一些性能优势,因为代码更简单,结果更可预测:例如,替换一个字符总是会产生与原始字符相同数量的字符。
在替换本身的性能方面并不太重要。在紧密循环中,“旧”字符串的分配和垃圾回收对替换本身的影响更大。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接