C# 搜索字符串只在第一次搜索时需要很长时间?
搜索字符串性能问题的方法很多,但我仍然不知道最好的方法是什么 长话短说,我已承诺从4NT迁移到PowerShell。在离开4NT时,我将错过它附带的控制台超级快速字符串搜索实用程序FFIND。我决定用我基本的C#编程技巧尝试创建一个我自己的实用程序,在PowerShell中使用,速度也一样快 到目前为止,对100个目录中的1000个文件(其中一些文件相当大)进行字符串搜索的搜索结果为FFIND 2.4秒,my utility为4.4秒。。。。。在我至少跑过一次之后 我第一次运行它们时,它几乎是在同一时间运行的,但我的运行时间超过一分钟?这是什么?图书馆的加载?文件索引?我的代码是否有问题?我不介意再等一段时间,但差别已经非常大,如果有更好的语言或方法,我宁愿现在就开始走这条路,以免我投资太多 我需要选择另一种语言来编写快速的字符串搜索吗 我需要使用这个工具在1000个文件中搜索web代码、C#代码和另一种使用文本文件的安抚语言中的字符串。我还需要能够使用此实用程序在非常大的日志文件(MB大小)中查找字符串C# 搜索字符串只在第一次搜索时需要很长时间?,c#,string,performance,C#,String,Performance,搜索字符串性能问题的方法很多,但我仍然不知道最好的方法是什么 长话短说,我已承诺从4NT迁移到PowerShell。在离开4NT时,我将错过它附带的控制台超级快速字符串搜索实用程序FFIND。我决定用我基本的C#编程技巧尝试创建一个我自己的实用程序,在PowerShell中使用,速度也一样快 到目前为止,对100个目录中的1000个文件(其中一些文件相当大)进行字符串搜索的搜索结果为FFIND 2.4秒,my utility为4.4秒。。。。。在我至少跑过一次之后 我第一次运行它们时,它几乎是在
class Program
{
public static int linecounter;
public static int filecounter;
static void Main(string[] args)
{
//
//INIT
//
filecounter = 0;
linecounter = 0;
string word;
// Read properties from application settings.
string filelocation = Properties.Settings.Default.FavOne;
// Set Args from console.
word = args[0];
//
//Recursive search for sub folders and files
//
string startDIR;
string filename;
startDIR = Environment.CurrentDirectory;
//startDIR = "c:\\SearchStringTestDIR\\";
filename = args[1];
DirSearch(startDIR, word, filename);
Console.WriteLine(filecounter + " " + "Files found");
Console.WriteLine(linecounter + " " + "Lines found");
Console.ReadKey();
}
static void DirSearch(string dir, string word, string filename)
{
string fileline;
string ColorOne = Properties.Settings.Default.ColorOne;
string ColorTwo = Properties.Settings.Default.ColorTwo;
ConsoleColor valuecolorone = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), ColorOne);
ConsoleColor valuecolortwo = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), ColorTwo);
try
{
foreach (string f in Directory.GetFiles(dir, filename))
{
StreamReader file = new StreamReader(f);
bool t = true;
int counter = 1;
while ((fileline = file.ReadLine()) != null)
{
if (fileline.Contains(word))
{
if (t)
{
t = false;
filecounter++;
Console.ForegroundColor = valuecolorone;
Console.WriteLine(" ");
Console.WriteLine(f);
Console.ForegroundColor = valuecolortwo;
}
linecounter++;
Console.WriteLine(counter.ToString() + ". " + fileline);
}
counter++;
}
file.Close();
file = null;
}
foreach (string d in Directory.GetDirectories(dir))
{
//Console.WriteLine(d);
DirSearch(d,word,filename);
}
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
如果你想加快你的代码运行性能分析,看看什么是最花时间。我几乎可以保证这里最长的一步是
fileline.Contains(word)
该函数在文件的每一行、每一个文件上都被调用。天真地搜索字符串中的单词可以进行len(字符串)*len(单词)比较
您可以编写自己的Contains方法,该方法使用更快的字符串比较算法。谷歌搜索“快速字符串精确匹配”。您可以尝试使用正则表达式,看看这是否能提高性能。但我认为您可以尝试的最简单优化是:
不要每行都读。创建一个包含文件所有内容的大字符串
StreamReader streamReader = new StreamReader(filePath, Encoding.UTF8);
string text = streamReader.ReadToEnd();
在此基础上运行
如果您需要一个文件中的所有匹配项,那么您需要使用以下内容
使用regex获取单个文件的所有匹配项后,可以迭代此匹配项集合(如果存在任何匹配项)。对于每个匹配,您可以通过编写一个函数来恢复原始文件的行,该函数从“匹配对象索引”属性向前和向后读取“\n”字符。然后输出这两个换行符之间的字符串,以获得您的换行符
我保证这会快得多
如果你想更进一步,我注意到以下几点:
从循环外部删除try-catch语句。只在你需要的地方使用它。我根本不会用它
还要确保你的系统正在运行,ngen。大多数设置通常都有此功能,但有时ngen没有运行。您可以在process explorer中看到该流程。Ngen生成C#managed字节码的本机映像,因此代码不必每次都进行解释,而是可以本机运行。这大大加快了C#的速度
编辑
其他要点:
为什么第一次和后续运行时间之间存在差异?看起来像是缓存。操作系统可以缓存目录、文件、运行和加载程序的请求。通常在第一次跑步后会看到加速。Ngen也可能在这里发挥作用,在第一次运行编译后生成本机映像,然后将其存储在本机映像缓存中
总的来说,我觉得C#的性能太多变了,我不喜欢。如果建议的优化不令人满意,并且您希望获得更一致的性能结果,请尝试另一种语言——一种不是“托管”的语言。C可能最适合您的需要。如果您想加快代码运行速度,请运行性能分析,看看什么花费的时间最多。我几乎可以保证这里最长的一步是
fileline.Contains(word)
该函数在文件的每一行、每一个文件上都被调用。天真地搜索字符串中的单词可以进行len(字符串)*len(单词)比较
您可以编写自己的Contains方法,该方法使用更快的字符串比较算法。谷歌搜索“快速字符串精确匹配”。您可以尝试使用正则表达式,看看这是否能提高性能。但我认为您可以尝试的最简单优化是:
不要每行都读。创建一个包含文件所有内容的大字符串
StreamReader streamReader = new StreamReader(filePath, Encoding.UTF8);
string text = streamReader.ReadToEnd();
在此基础上运行
如果您需要一个文件中的所有匹配项,那么您需要使用以下内容
使用regex获取单个文件的所有匹配项后,可以迭代此匹配项集合(如果存在任何匹配项)。对于每个匹配,您可以通过编写一个函数来恢复原始文件的行,该函数从“匹配对象索引”属性向前和向后读取“\n”字符。然后输出这两个换行符之间的字符串,以获得您的换行符
我保证这会快得多
如果你想更进一步,我注意到以下几点:
从循环外部删除try-catch语句。只在你需要的地方使用它。我根本不会用它
还要确保你的系统正在运行,ngen。大多数设置通常都有此功能,但有时ngen没有运行。您可以在process explorer中看到该流程。Ngen生成C#managed字节码的本机映像,因此代码不必每次都进行解释,而是可以本机运行。这大大加快了C#的速度
编辑
其他要点:
为什么第一次和后续运行时间之间存在差异?看起来像是缓存。操作系统可以缓存目录、文件、运行和加载程序的请求。通常是一个se