C# String.Contains()比String.IndexOf()快吗?
我有一个大约2000个字符的字符串缓冲区,需要检查缓冲区是否包含特定字符串。C# String.Contains()比String.IndexOf()快吗?,c#,.net,asp.net,performance,string,C#,.net,Asp.net,Performance,String,我有一个大约2000个字符的字符串缓冲区,需要检查缓冲区是否包含特定字符串。 将为每个webrequest签入ASP.NET 2.0 webapp。 是否有人知道该系统的性能是否优于? 也许,这一点都不重要。阅读这篇关于编写恐怖代码的帖子;): 使用基准库,比如测量它 与所有(微观)性能问题一样,这取决于您使用的软件版本、所检查数据的详细信息以及围绕调用的代码 正如所有(微观)性能问题一样,第一步必须是获得易于维护的运行版本。然后,可以对测量的瓶颈进行基准测试、分析和调整,而不是猜测。从一点阅读
将为每个webrequest签入ASP.NET 2.0 webapp。
是否有人知道该系统的性能是否优于?
也许,这一点都不重要。阅读这篇关于编写恐怖代码的帖子;): 使用基准库,比如测量它 与所有(微观)性能问题一样,这取决于您使用的软件版本、所检查数据的详细信息以及围绕调用的代码
正如所有(微观)性能问题一样,第一步必须是获得易于维护的运行版本。然后,可以对测量的瓶颈进行基准测试、分析和调整,而不是猜测。从一点阅读中,可以看出String.Contains方法只是调用String.IndexOf。差异是String.Contains返回一个布尔值,而String.IndexOf返回一个带(-1)的整数,表示未找到子字符串 我建议写一个大约100000次迭代的小测试,自己看看。如果我猜的话,我会说IndexOf可能会稍微快一点,但就像我说的,这只是一个猜测
杰夫·阿特伍德(Jeff Atwood)在美国有一篇关于弦的好文章。这更多的是关于连接,但可能会有所帮助 您可以看到,通过使用Reflector,包含的是使用IndexOf实现的。下面是实现
public bool Contains(string value)
{
return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
}
所以Contains可能比直接调用IndexOf慢一点,但我怀疑它对实际性能是否有任何意义
包含调用IndexOf
:
public bool Contains(string value)
{
return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
}
调用CompareInfo.IndexOf
,最终使用CLR实现
public bool Contains(string value)
{
return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
}
如果您想查看如何在CLR中比较字符串(请查找CaseInsensitiveCompHelper)
IndexOf(string)
没有选项,并且Contains()
使用顺序比较(逐字节比较,而不是尝试执行智能比较,例如e withé)
因此,IndexOf
将稍微快一点(理论上),因为IndexOf
直接使用kernel32.dll中的FindNLSString进行字符串搜索(reflector的威力!)
为.NET 4.0更新了-IndexOf不再使用顺序比较,因此包含速度更快。请参阅下面的评论。如果您真的想对代码进行微优化,最好的方法始终是基准测试
.net framework有一个优秀的秒表实现--Contains(s2)比IndexOf(s2)快很多倍(在我的计算机中是10倍),因为Contains使用StringComparison.Ordinal,比IndexOf默认情况下进行的区域性敏感搜索快(但在.net 4.0中可能会发生变化)
在我的测试中,Contains与IndexOf(s2,StringComparison.Ordinal)>=0的性能完全相同,但它较短,并且清楚地表明了您的意图。作为对此的更新,我已经做了一些测试,如果您的输入字符串相当大,那么并行正则表达式是我发现的最快的C#方法(假设你有一个以上的核心,我想)
例如,获取匹配的总数-
needles.AsParallel ( ).Sum ( l => Regex.IsMatch ( haystack , Regex.Escape ( l ) ) ? 1 : 0 );
希望这有帮助!我正在运行一个真实的案例(与合成基准相反)
if(“=,,,,!=,=,”.IndexOf(tmps)>=0){
对
if("=,<=,=>,<>,<,>,!=,==,".Contains(tmps)) {
如果(“=,,,!=,=,=,”。包含(TMP)){
它是我的系统的重要组成部分,执行了131953次(感谢DotTrace)
然而,令人震惊的惊喜,结果与预期相反
- 指数为533ms
- 包含266ms
:-/
net framework 4.0(更新日期为2012年2月13日)对于仍在阅读本文的人来说,indexOf()可能会在大多数企业系统上表现更好,就像contains()一样与IE不兼容!今天在一个1.3 GB的文本文件上试用了它。除其他外,每一行都检查是否存在'@'字符。对Contains/IndexOf进行了17.000.000次调用。结果:所有Contains('@')调用12.5秒,对所有IndexOf('@')调用2.5秒。=>IndexOf执行速度快5倍!!(.Net 4.8)如果您需要在每个web请求中执行十亿次,我将开始研究类似的内容。在任何其他情况下,我都不会费心,因为与最初接收HTTP请求相比,在任何一种方法中花费的时间都可能微不足道。优化的关键之一是测试而不是assuming,因为它可能取决于许多因素,如.NET版本、操作系统、硬件、输入变化等。在许多情况下,其他人在您的系统上所做的测试结果可能会非常不同。是的,但要使用indexof作为bool,他必须在函数之外进行比较。这很可能会给出与Co相同的结果ntains,不是吗?可能吧,但您确实保存了一个方法调用(除非它可以内联).正如我所说,它可能永远不会有意义。讨好老板我们是不是…?:D你是对的,与服务http请求所花费的时间相比,搜索短字符串一次并不重要。这是一个非常有趣的阅读,但它困扰着我。他最初抱怨的连接是内存使用,然后他只测试花在组合字符串的各种方法上的时间。Hi phild在一个单独的线程上更新了这个版本,从中提供了您的关键字(针)不要更改要快得多。在.NET 4.0中的更改显然是在它进入RTM之前恢复的,所以我不会太依赖那篇文章,因为INT
比BOOL
大得多,并且IndexOf>=0
会导致又一步您忘记使用“StringComparison.Ordinal”。虽然这个链接可能会回答这个问题,但它是正确的请在此处包含答案的基本部分,并提供链接以供参考。仅链接
if("=,<=,=>,<>,<,>,!=,==,".Contains(tmps)) {