c# - Boyer-Moore 在 C# 中实用吗?

标签 c# .net algorithm performance boyer-moore

Boyer-Moore 可能是已知最快的非索引文本搜索算法。所以我在 C# 中为我的 Black Belt Coder 实现它网站。

我让它运行起来,与 String.IndexOf() 相比,它大致显示出预期的性能改进。但是,当我将 StringComparison.Ordinal 参数添加到 IndexOf 时,它的性能开始优于我的 Boyer-Moore 实现。有时,数量可观。

不知道有没有人能帮我弄清楚原因。我明白为什么 StringComparision.Ordinal 可能会加快速度,但它怎么可能比 Boyer-Moore 更快呢?是因为 .NET 平台本身的开销,也许是因为必须验证数组索引以确保它们在范围内,或者其他原因。有些算法在 C#.NET 中不实用吗?

下面是关键代码。

// Base for search classes
abstract class SearchBase
{
    public const int InvalidIndex = -1;
    protected string _pattern;
    public SearchBase(string pattern) { _pattern = pattern; }
    public abstract int Search(string text, int startIndex);
    public int Search(string text) { return Search(text, 0); }
}

/// <summary>
/// A simplified Boyer-Moore implementation.
/// 
/// Note: Uses a single skip array, which uses more memory than needed and
/// may not be large enough. Will be replaced with multi-stage table.
/// </summary>
class BoyerMoore2 : SearchBase
{
    private byte[] _skipArray;

    public BoyerMoore2(string pattern)
        : base(pattern)
    {
        // TODO: To be replaced with multi-stage table
        _skipArray = new byte[0x10000];

        for (int i = 0; i < _skipArray.Length; i++)
            _skipArray[i] = (byte)_pattern.Length;
        for (int i = 0; i < _pattern.Length - 1; i++)
            _skipArray[_pattern[i]] = (byte)(_pattern.Length - i - 1);
    }

    public override int Search(string text, int startIndex)
    {
        int i = startIndex;

        // Loop while there's still room for search term
        while (i <= (text.Length - _pattern.Length))
        {
            // Look if we have a match at this position
            int j = _pattern.Length - 1;
            while (j >= 0 && _pattern[j] == text[i + j])
                j--;

            if (j < 0)
            {
                // Match found
                return i;
            }

            // Advance to next comparision
            i += Math.Max(_skipArray[text[i + j]] - _pattern.Length + 1 + j, 1);
        }
        // No match found
        return InvalidIndex;
    }
}

编辑:我已经在 http://www.blackbeltcoder.com/Articles/algorithms/fast-text-search-with-boyer-moore 上发布了我所有的测试代码和关于此事的结论。 .

最佳答案

根据我自己的测试和此处的评论,我得出结论,String.IndexOf()StringComparision.Ordinal 一起执行得很好的原因是因为方法调用可能采用手动优化的汇编语言的非托管代码。

我运行了许多不同的测试,String.IndexOf() 似乎比我使用托管 C# 代码实现的任何东西都要快。

如果有人感兴趣,我已经写下了我发现的所有相关内容,并在 http://www.blackbeltcoder.com/Articles/algorithms/fast-text-search-with-boyer-moore 上用 C# 发布了 Boyer-Moore 算法的几个变体。 .

关于c# - Boyer-Moore 在 C# 中实用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4904705/

相关文章:

c# - 什么是更有效的三角形分类方法?

c# - NSMutableArray 和 NSArray 在 C# 中的等效项是什么?

javascript - 有效地找到将较小的箱子分配给较大的箱子的每个组合

algorithm - 在集合的分区上最大化 AND 和 XOR 的 bool 函数

c# - Travian 更改村庄名称给 'Invalid Token' 与 webrequests

c# - 流利的 nhibernate 多对多与以下多对多映射

c - 我在 EFCore 中使用同一连接的多个上下文时遇到问题。如果有人能帮助我,我将非常感激

c# - SQL:使用带有 LIMIT 的 INNER JOIN 进行更新

渐进矩阵算法

c# - 如何在C#中编写sql语句来连接数据