【问题标题】:is String.Contains() faster than walking through whole array of char in string?String.Contains() 是否比遍历字符串中的整个字符数组更快?
【发布时间】:2013-04-19 09:00:09
【问题描述】:

我有一个函数遍历字符串寻找模式并改变它的一部分。我可以通过插入优化它

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;
    }

【问题讨论】:

  • 您必须发布(概述)其余代码。但是,是的,你很可能在这里做双重工作。
  • 为什么不在 for 循环中对这两种方法计时?
  • “那么,尝试这样的优化是个好主意吗?”几乎可以肯定不是!这一定是库中最常用的函数之一。它受到了很多关注。很难想象你可以改进它,除非非常特殊的情况和真正敬业的专家。
  • 遍历字符串、匹配模式、更改字符串...也许您还想计算正则表达式的执行方式。
  • 您可能还想用字符串的 IndexOf 方法替换找到位置的代码。比如position = text.IndexOf(colorchar); 然后position = text.IndexOf(colorchar, position);

标签: c# performance


【解决方案1】:

简短的回答是,您的优化根本不是优化。
基本上,String.Contains(...) 只返回String.IndexOf(..) &gt;= 0
您可以将您的算法改进为:

int position = text.IndexOf(colorchar.ToString()...);
if (-1 < position)
{  /* Do it */ }

【讨论】:

    【解决方案2】:

    是的。

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

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

    此外,IIRC String.Contains 的来源在 .Net 共享源中可用

    哦,如果您想要进行性能比较,您可以针对您的确切用例进行测量

    【讨论】:

      【解决方案3】:

      查看此类似帖子How does string.contains work

      我认为你将无法简单地做任何比 String.Contains 更快的事情,除非你想使用标准 CRT 函数 wcsstr,在 msvcrt.dll 中可用,这并不容易

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          【解决方案5】:

          如果您现在了解可用于优化的详细信息(不仅仅是简单的包含检查),请确保您可以使您的方法比 string.Contains 更快,否则 - 不会。

          【讨论】:

            猜你喜欢
            • 2021-11-16
            • 1970-01-01
            • 2014-06-16
            • 2015-09-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多