Pra*_*eep 42 .net regex string
这两个等效表达式的速度/内存使用有什么不同:
Regex.IsMatch(Message, "1000")
Run Code Online (Sandbox Code Playgroud)
VS
Message.Contains("1000")
Run Code Online (Sandbox Code Playgroud)
任何一个比其他更好的情况?
这个问题的上下文如下:我正在对包含Regex表达式的遗留代码进行一些更改,以查找字符串是否包含在另一个字符串中.作为遗留代码,我没有对此进行任何更改,在代码审查中有人建议Regex.IsMatch应该替换为string.Contains.所以我想知道改变是否值得.
And*_*are 43
对于简单的情况,String.Contains将为您提供更好的性能,但String.Contains不允许您进行复杂的模式匹配.使用String.Contains非模式匹配的情况(像在你的例子),并使用正则表达式中,你需要做更复杂的模式匹配的情况.
正则表达式有一定的开销与它相关联(表达式解析,编译,执行等),简单的方法就像一个简单的方法String.Contains没有,这就是为什么String.Contains在像你这样的例子中胜过正则表达式.
use*_*470 36
String.Contains将它与编译的正则表达式进行比较时,速度会变慢.相当慢,甚至!
您可以测试运行此基准测试:
class Program
{
public static int FoundString;
public static int FoundRegex;
static void DoLoop(bool show)
{
const string path = "C:\\file.txt";
const int iterations = 1000000;
var content = File.ReadAllText(path);
const string searchString = "this exists in file";
var searchRegex = new Regex("this exists in file");
var containsTimer = Stopwatch.StartNew();
for (var i = 0; i < iterations; i++)
{
if (content.Contains(searchString))
{
FoundString++;
}
}
containsTimer.Stop();
var regexTimer = Stopwatch.StartNew();
for (var i = 0; i < iterations; i++)
{
if (searchRegex.IsMatch(content))
{
FoundRegex++;
}
}
regexTimer.Stop();
if (!show) return;
Console.WriteLine("FoundString: {0}", FoundString);
Console.WriteLine("FoundRegex: {0}", FoundRegex);
Console.WriteLine("containsTimer: {0}", containsTimer.ElapsedMilliseconds);
Console.WriteLine("regexTimer: {0}", regexTimer.ElapsedMilliseconds);
Console.ReadLine();
}
static void Main(string[] args)
{
DoLoop(false);
DoLoop(true);
return;
}
}
Run Code Online (Sandbox Code Playgroud)
要确定哪个是最快的,您将需要对自己的系统进行基准测试.但是,正则表达式很复杂,而且String.Contains()很有可能是最快的,在您的情况下也是最简单的解决方案.
String.Contains()最终的实现将调用本机方法 IndexOfString(),并且只有Microsoft知道它的实现.然而,用于实现该方法的良好算法使用所谓的Knuth-Morris-Pratt算法.这个算法的复杂性是O(m + n),其中m是你要搜索的字符串的长度,n是你正在搜索的字符串的长度,使它成为一个非常有效的算法.
实际上,使用正则表达式的搜索效率可以是低O(n),具体取决于实现,因此在某些情况下它仍然具有竞争性.只有基准测试才能确定这一点.
如果你真的关心搜索速度,Christian Charras和Thierry Lecroq 在UniversitédeRouen 有很多关于精确字符串匹配算法的资料.
小智 6
@ user279470我一直在寻找一种有效的方式来计算单词以获得乐趣,并且遇到了这个问题.我给了它OpenOffice Thesaurus dat文件来迭代.总字数达到1575423.
现在,我的最终目标没有用于包含,但有趣的是看到你可以调用正则表达式的不同方法,使其更快.我创建了一些其他方法来比较正则表达式的实例使用和静态使用与RegexOptions.compiled.
public static class WordCount
{
/// <summary>
/// Count words with instaniated Regex.
/// </summary>
public static int CountWords4(string s)
{
Regex r = new Regex(@"[\S]+");
MatchCollection collection = r.Matches(s);
return collection.Count;
}
/// <summary>
/// Count words with static compiled Regex.
/// </summary>
public static int CountWords1(string s)
{
MatchCollection collection = Regex.Matches(s, @"[\S]+", RegexOptions.Compiled);
return collection.Count;
}
/// <summary>
/// Count words with static Regex.
/// </summary>
public static int CountWords3(string s)
{
MatchCollection collection = Regex.Matches(s, @"[\S]+");
return collection.Count;
}
/// <summary>
/// Count word with loop and character tests.
/// </summary>
public static int CountWords2(string s)
{
int c = 0;
for (int i = 1; i < s.Length; i++)
{
if (char.IsWhiteSpace(s[i - 1]) == true)
{
if (char.IsLetterOrDigit(s[i]) == true ||
char.IsPunctuation(s[i]))
{
c++;
}
}
}
if (s.Length > 2)
{
c++;
}
return c;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
44978 次 |
| 最近记录: |