Boyer-Moore可能是已知最快的非索引文本搜索算法。因此,我在Black Belt Coder网站的C#中实现了它。
我已将其工作,并且与相比,它大致显示了预期的性能改进String.IndexOf()。但是,当我将StringComparison.Ordinal参数添加到时IndexOf,它开始优于我的Boyer- Moore实现。有时,数量可观。
String.IndexOf()
StringComparison.Ordinal
IndexOf
我想知道是否有人可以帮助我找出原因。我知道为什么StringComparision.Ordinal可以加快速度,但是怎么会比Boyer- Moore更快呢?是因为.NET平台本身的开销,还是因为必须验证数组索引以确保它们在范围之内,或者其他原因。有些算法在C#.NET中不实用吗?
StringComparision.Ordinal
下面是关键代码。
// 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-上发布 C#中的Boyer-Moore算法的几种变体。博耶- 穆尔。