在字符串中,String.Contains() 比遍历整个字符数组更快吗?

5
我有一个函数,它会遍历字符串查找模式并更改其中的一部分。我可以通过插入代码来进行优化。
if (!text.Contains(pattern)) return;

但是,实际上我正在遍历整个字符串,并将其部分与模式进行比较,所以问题是,String.Contains() 如何工作?我知道有这样一个问题 - How does String.Contains work? 但是答案不太清楚。因此,如果String.Contains()也遍历整个字符数组并将它们与我要查找的模式进行比较,那么它实际上不会使我的函数更快,而是会变得更慢。

那么,尝试这样的优化是否是一个好主意呢?而且,String.Contains() 是否可能比只遍历整个数组并将每个字符与某个常量字符进行比较的函数更快呢?

以下是代码:

    public static char colorchar = (char)3;

    public static Client.RichTBox.ContentText color(string text, Client.RichTBox SBAB)
    {
        if (text.Contains(colorchar.ToString()))
        {
            int color = 0;
            bool closed = false;
            int position = 0;
            while (text.Length > position)
            {
                if (text[position] == colorchar)
                {
                    if (closed)
                    {
                        text = text.Substring(position, text.Length - position);
                        Client.RichTBox.ContentText Link = new Client.RichTBox.ContentText(ProtocolIrc.decode_text(text), SBAB, Configuration.CurrentSkin.mrcl[color]);
                        return Link;
                    }

                    if (!closed)
                    {
                        if (!int.TryParse(text[position + 1].ToString() + text[position + 2].ToString(), out color))
                        {
                            if (!int.TryParse(text[position + 1].ToString(), out color))
                            {
                                color = 0;
                            }
                        }
                        if (color > 9)
                        {
                            text = text.Remove(position, 3);
                        }
                        else
                        {
                            text = text.Remove(position, 2);
                        }
                        closed = true;
                        if (color < 16)
                        {
                            text = text.Substring(position);
                            break;
                        }
                    }
                }
                position++;
            }
        }
        return null;
    }

4
为什么不在一个for循环中计时两种方法呢? - Habib
@Habib 这不是个坏主意 :) - Petr
2
那么,尝试这样的优化是个好主意吗?几乎肯定不是!这必须是库中最常用的函数之一。它已经受到了很多关注。很难想象除非在非常特殊的情况下,并且由真正专注的专家来改进它。 - Thilo
1
遍历字符串,匹配模式,更改字符串...也许您还想计算正则表达式的性能。 - Corak
1
你可能想要使用字符串的IndexOf方法来替换查找位置的代码,例如 position = text.IndexOf(colorchar); 然后 position = text.IndexOf(colorchar, position); - Andrei Zubov
显示剩余2条评论
5个回答

1
简短的回答是,你的优化根本不算优化。
基本上,String.Contains(...) 只是返回 String.IndexOf(..) >= 0
你可以改进你的算法为:
int position = text.IndexOf(colorchar.ToString()...);
if (-1 < position)
{  /* Do it */ }

0

是的。

而且没有错误(啊嗯……)。

在非常长的文本中查找多个子字符串有更好的方法,但对于大多数常见用途,String.Contains(或IndexOf)是最好的选择。

此外,如果我没记错的话,String.Contains的源代码可以在.Net共享源代码中获得。

哦,如果你想进行性能比较,只需针对你的确切用例进行测量即可。


0

请查看类似的帖子如何使用string.contains

我认为,除非你想使用msvcrt.dll中提供的标准CRT函数wcsstr,否则你将无法比String.Contains更快地完成任何操作,这并不容易。


0

除非您已经对应用程序进行了分析,并确定带有String.Contains的行是瓶颈,否则您不应该进行此类过早的优化。保持代码意图清晰要比任何优化更重要。

虽然在.NET基类中实现方法的方式有很多种,但您应该假设默认实现对大多数人的使用情况已经足够优化。例如,任何(未来).NET的实现都可能使用x86特定指令进行字符串比较。那样总是比您在C#中所能做的更快。

如果您真的想确保自定义字符串比较代码比String.Contains更快,您需要使用许多迭代来测量它们,每个迭代都使用不同的字符串。例如使用Stopwatch来测量时间。


0

如果您知道可以用于优化的详细信息(不仅仅是简单的包含检查),那么您肯定可以使您的方法比string.Contains更快,否则就不行。


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