如何优化此功能?c#扫描文本文件中的字符串

如何优化此功能?c#扫描文本文件中的字符串,c#,.net,performance,C#,.net,Performance,我正在编写一个程序来扫描文本文件中的字符串块(行),并在找到时将这些块输出到文件中 在我的process类中,函数proc()处理6MB文件的时间异常长。在我之前编写的一个程序中,我只扫描文本中一种特定类型的字符串,处理同一个文件需要5秒钟。现在我重写它来扫描不同字符串的存在。这需要超过8分钟,这是一个显著的区别。有人知道如何优化这个功能吗 这是我的正则表达式 System.Text.RegularExpressions.Regex RegExp { get { return new Syste

我正在编写一个程序来扫描文本文件中的字符串块(行),并在找到时将这些块输出到文件中 在我的process类中,函数proc()处理6MB文件的时间异常长。在我之前编写的一个程序中,我只扫描文本中一种特定类型的字符串,处理同一个文件需要5秒钟。现在我重写它来扫描不同字符串的存在。这需要超过8分钟,这是一个显著的区别。有人知道如何优化这个功能吗

这是我的正则表达式

System.Text.RegularExpressions.Regex RegExp { get { return new System.Text.RegularExpressions.Regex(@"(?s)(?-m)MSH.+?(?=[\r\n]([^A-Z0-9]|.{1,2}[^A-Z0-9])|$)", System.Text.RegularExpressions.RegexOptions.Compiled); } }

公共静态类类型工厂
{
公共静态列表GetTypeList()
{
列表类型=新列表();
types.AddRange(来自AppDomain.CurrentDomain.GetAssemblys()中的程序集)
来自assembly.GetTypes()中的t
其中t.IsClass&&t.GetInterfaces()包含(typeof(IMessageType))
选择Activator.CreateInstance(t)作为IMessageType);
返回类型;
}
}
公共类过程
{
公开作废程序()
{
IOHandler.Read reader=new IOHandler.Read(新字符串[1]{@“C:\TEMP\DeIdentified\DId\u RSLTXMIT.LOG”});
列表类型=MessageType.TypeFactory.GetTypeList();
//测试1
IOHandler.Write.writeReport(System.DateTime.Now.ToString(),“TEST”,“v3test.txt”,true);
foreach(reader.FileList中的字符串文件)
{
使用(FileStream readStream=newfilestream(file,FileMode.Open,FileAccess.Read))
{
int charVal=0;
Int64位置=0;
StringBuilder fileFragment=新的StringBuilder();
string message=string.Empty;
string current=string.Empty;
string previous=string.Empty;
int currentLength=0;
int-previousLength=0;
bool-found=false;
做
{
//字符串行=reader.ReturnLine(readStream、out charVal、ref位置);
字符串行=reader.ReturnLine(readStream,out charVal);
for(int i=0;i


编辑:我在VS2012中运行了评测向导,发现大部分时间都花在正则表达式上。匹配函数

  • 正则表达式匹配不是执行子字符串搜索的最有效方法,并且您将对每个“类型”的匹配执行一次匹配检查。看看高效的子字符串匹配算法,比如是否需要匹配文字子字符串而不是模式
  • 如果必须使用正则表达式,考虑.
  • 使用BufferedStream提高IO性能。对于一个6MB的文件来说可能是边缘的,但它只需要一行代码
  • 使用探查器来确保时间准确地花在哪里

    • 以下是一些想法:

      • 正则表达式匹配不是执行子字符串搜索的最有效方法,并且您将对每个“类型”的匹配执行一次匹配检查。看看高效的子字符串匹配算法,比如是否需要匹配文字子字符串而不是模式
      • 如果必须使用正则表达式,考虑.
      • 使用BufferedStream提高IO性能。对于一个6MB的文件来说可能是边缘的,但它只需要一行代码
      • 使用探查器来确保时间准确地花在哪里
      高层次理念:

    • 使用Regex.Matches一次查找所有匹配项,而不是逐个查找。可能是主要的表演

    • 预构建搜索模式以一次包含多条消息。您可以使用正则表达式或

    • 高层次的想法:

    • 使用Regex.Matches一次查找所有匹配项,而不是逐个查找。可能是主要的表演

    • 预构建搜索模式以一次包含多条消息。您可以使用正则表达式或


    • 您是否尝试过分析代码以查看瓶颈在哪里?您还可以实现一个基本的记录器,在每个位置放置一个
      时间戳
      ,以便在分析器没有帮助的情况下找到瓶颈。当我看到
      StringBuilder
      时,我对您使用它寄予厚望
       public static class TypeFactory
      {
          public static List<IMessageType> GetTypeList()
          {
              List<IMessageType> types = new List<IMessageType>();
              types.AddRange(from assembly in AppDomain.CurrentDomain.GetAssemblies()
                             from t in assembly.GetTypes()
                             where t.IsClass && t.GetInterfaces().Contains(typeof(IMessageType))
                             select Activator.CreateInstance(t) as IMessageType);
      
              return types;
          }
      }
      
      public class process
      {
      
      
          public void proc()
          {
              IOHandler.Read reader = new IOHandler.Read(new string[1] { @"C:\TEMP\DeIdentified\DId_RSLTXMIT.LOG" });
      
              List<IMessageType> types = MessageType.TypeFactory.GetTypeList();
      
              //TEST1
              IOHandler.Write.writeReport(System.DateTime.Now.ToString(), "TEST", "v3test.txt", true);
      
              foreach (string file in reader.FileList)
              {
                  using (FileStream readStream = new FileStream(file, FileMode.Open, FileAccess.Read))
                  {
                      int charVal = 0;
                      Int64 position = 0;
                      StringBuilder fileFragment = new StringBuilder();
                      string message = string.Empty;
      
                      string current = string.Empty;
                      string previous = string.Empty;
      
                      int currentLength = 0;
                      int previousLength = 0;
      
                      bool found = false;
      
                      do
                      {
                          //string line = reader.ReturnLine(readStream, out charVal, ref position);
                          string line = reader.ReturnLine(readStream, out charVal);
      
                          for (int i = 0; i < types.Count; i++)
                          {
                              if (Regex.IsMatch(line, types[i].BeginIndicator)) //found first line of a message type
                              {
                                  found = true;
                                  message += line;
      
                                  do
                                  {
                                      previousLength = types[i].RegExp.Match(message).Length;
      
                                      //keep adding lines until match length stops growing
                                      //message += reader.ReturnLine(readStream, out charVal, ref position);
                                      message += reader.ReturnLine(readStream, out charVal);
                                      currentLength = types[i].RegExp.Match(message).Length;
      
                                      if (currentLength == previousLength)
                                      {
                                          //stop - message complete
                                          IOHandler.Write.writeReport(message, "TEST", "v3test.txt", true);
      
                                          //reset
                                          message = string.Empty;
                                          currentLength = 0;
                                          previousLength = 0;
                                          break;
                                      }
      
      
                                  } while (charVal != -1);
      
      
      
                                  break;
                              }
                          }
      
      
      
      
                      } while (charVal != -1);
      
      
                      //END OF FILE CONDITION
                      if (charVal == -1)
                      {
      
                      }
      
                  }
      
              }
              IOHandler.Write.writeReport(System.DateTime.Now.ToString(), "TEST", "v3test.txt", true);
          }
      }