c# - C#的string.IndexOf怎么能执行的这么快,比普通的for循环find快10倍?

标签 c# string search indexof

我有一个很长的字符串(大小为 60MB),我需要找出其中有多少对“<”和“>”。


我首先尝试了自己的方法:

        char pre = '!';
        int match1 = 0;
        for (int j = 0; j < html.Length; j++)
        {
            char c = html[j];
            if (pre == '<' && c == '>') //find a match
            {
                pre = '!';
                match1++;
            }
            else if (pre == '!' && c == '<')
                pre = '<';
        }

以上代码在我的字符串上运行了大约 1000 毫秒


然后我尝试使用 string.IndexOf

        int match2 = 0;
        int index = -1;
        do
        {
            index = html.IndexOf('<', index + 1);
            if (index != -1) // find a match
            {
                index = html.IndexOf('>', index + 1);
                if (index != -1)
                   match2++;
            }
        } while (index != -1);

以上代码只运行了大约 150 毫秒


我想知道是什么让 string.IndexOf 运行这么快

谁能启发我?


编辑

好的,根据@BrokenGlass的回答。我修改了我的代码,他们不检查配对,而是检查字符串中有多少个“<”。


        for (int j = 0; j < html.Length; j++)
        {
            char c = html[j];
            if (c == '>')
            {
                match1++;
            }
        }

以上代码运行了大约 760 毫秒


使用 IndexOf

        int index = -1;
        do
        {
            index = html.IndexOf('<', index + 1);
            if (index != -1)
            {
                match2++;
            }
        } while (index != -1);

以上代码运行了大约 132 毫秒仍然非常非常快。


编辑2

阅读@Jeffrey Sax 的评论后,我意识到我正在 VS 中以 Debug模式运行。

然后我构建并在 Release模式下运行,好的,IndexOf 仍然更快,但不再那么快了。

结果如下:

对于配对计数:207ms VS 144ms

对于正常的一个字符计数:141ms VS 111ms

我自己的代码的性能确实得到了提高。


经验教训:当您进行基准测试时,请在 Release模式下进行!

最佳答案

您是否在 Visual Studio 中运行计时?如果是这样,仅此一个原因,您的代码运行速度就会明显变慢。

除此之外,在某种程度上,您是在比较苹果和橙子。这两种算法以不同的方式工作。

IndexOf 版本在查找左括号 和右括号 之间交替。您的代码遍历整个字符串并保留一个状态标志,指示它是在寻找左括号还是右括号。这需要更多的工作,预计会更慢。

下面是一些代码,它以与您的 IndexOf 方法相同的方式进行比较。

int match3 = 0;
for (int j = 0; j < html.Length; j++) {
    if (html[j] == '<') {
        for (; j < html.Length; j++)
            if (html[j] == '>')
                match3++;
    }
}

在我的测试中,这实际上比 IndexOf 方法快 3 倍。原因?字符串实际上不像单个字符的序列那么简单。有标记、重音等。String.IndexOf 可以正确处理所有这些额外的复杂性,但这是有代价的。

关于c# - C#的string.IndexOf怎么能执行的这么快,比普通的for循环find快10倍?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10519380/

相关文章:

r - 在 data.frame 中跨列搜索的更简单的解决方案

c# - 如何测量一把锁的争用率

c# - 如何修复 Mono 3.0.3、Entity Framework 6 Beta2 和 Npgsql 上 MVC3 项目的 DbProviderServices 继承错误?

c# - 具有 TimeSpan 数据类型的 DataView RowFilter

mysql - 在 MySQL 的文本列中搜索字符串

linux - 在 Linux 下添加 Sphinx 搜索守护进程作为服务。

C# int 到标志枚举

c# - 仅当存在时从行首删除指定文本 (C#)

c - K+R 2.4 : bus error when assigning (Mac OS)

mysql - 续集专业版 : How to change a string to a date during import?