gpt4 book ai didi

c# - 在 C# 中查看一个字符串是否包含另一个字符串的最快、不区分大小写的方法是什么?

转载 作者:可可西里 更新时间:2023-11-01 08:41:36 26 4
gpt4 key购买 nike

编辑 2:

确认我的性能问题是由于对 StringExtensions 类的静态函数调用造成的。删除后,IndexOf 方法确实是完成此操作的最快方法。

在 C# 中查看一个字符串是否包含另一个字符串的最快、不区分大小写的方法是什么?我在 Case insensitive 'Contains(string)' 看到该帖子的公认解决方案但我已经做了一些初步的基准测试,似乎使用该方法会导致在找不到测试字符串时对较大字符串(> 100 个字符)的调用速度降低几个数量级。

以下是我知道的方法:

索引:

public static bool Contains(this string source, string toCheck, StringComparison comp)
{
if (string.IsNullOrEmpty(toCheck) || string.IsNullOrEmpty(source))
return false;

return source.IndexOf(toCheck, comp) >= 0;
}

到上层:

source.ToUpper().Contains(toCheck.ToUpper());

正则表达式:

bool contains = Regex.Match("StRiNG to search", "string", RegexOptions.IgnoreCase).Success;

所以我的问题是,平均而言哪种方式确实最快,为什么会这样?

编辑:

这是我用来强调性能差异的简单测试应用程序。使用它,我看到 ToLower() 为 16 毫秒,ToUpper 为 18 毫秒,StringExtensions.Contains() 为 140 毫秒:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace ScratchConsole
{
class Program
{
static void Main(string[] args)
{
string input = "";
while (input != "exit")
{
RunTest();
input = Console.ReadLine();
}
}

static void RunTest()
{
List<string> s = new List<string>();
string containsString = "1";
bool found;
DateTime now;
for (int i = 0; i < 50000; i++)
{
s.Add("AAAAAAAAAAAAAAAA AAAAAAAAAAAA");
}

now = DateTime.Now;
foreach (string st in s)
{
found = st.ToLower().Contains(containsString);
}
Console.WriteLine("ToLower(): " + (DateTime.Now - now).TotalMilliseconds);

now = DateTime.Now;
foreach (string st in s)
{
found = st.ToUpper().Contains(containsString);
}
Console.WriteLine("ToUpper(): " + (DateTime.Now - now).TotalMilliseconds);


now = DateTime.Now;
foreach (string st in s)
{
found = StringExtensions.Contains(st, containsString, StringComparison.OrdinalIgnoreCase);
}
Console.WriteLine("StringExtensions.Contains(): " + (DateTime.Now - now).TotalMilliseconds);

}
}

public static class StringExtensions
{
public static bool Contains(this string source, string toCheck, StringComparison comp)
{
return source.IndexOf(toCheck, comp) >= 0;
}
}

最佳答案

由于 ToUpper 实际上会导致创建一个新字符串,因此 StringComparison.OrdinalIgnoreCase 会更快,而且,正则表达式对于像这样的简单比较有很多开销。也就是说, String.IndexOf(String, StringComparison.OrdinalIgnoreCase) 应该是最快的,因为它不涉及创建新字符串。

我猜(我又来了)RegEx 有更好的最坏情况,因为它如何评估字符串,IndexOf 将始终进行线性搜索,我猜(再一次)RegEx 使用了一些东西更好的。 RegEx 也应该有一个最好的情况,它可能接近,但不如 IndexOf 好(由于它的语言更复杂)。

15,000 length string, 10,000 loop

00:00:00.0156251 IndexOf-OrdinalIgnoreCase
00:00:00.1093757 RegEx-IgnoreCase
00:00:00.9531311 IndexOf-ToUpper
00:00:00.9531311 IndexOf-ToLower

Placement in the string also makes a huge difference:

At start:
00:00:00.6250040 Match
00:00:00.0156251 IndexOf
00:00:00.9687562 ToUpper
00:00:01.0000064 ToLower

At End:
00:00:00.5781287 Match
00:00:01.0468817 IndexOf
00:00:01.4062590 ToUpper
00:00:01.4218841 ToLower

Not Found:
00:00:00.5625036 Match
00:00:01.0000064 IndexOf
00:00:01.3750088 ToUpper
00:00:01.3906339 ToLower

关于c# - 在 C# 中查看一个字符串是否包含另一个字符串的最快、不区分大小写的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7759902/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com