1

我正在编写一个程序来扫描文本文件中的字符串块(行),并在找到时将块输出到文件在我的进程类中,函数 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); } }

.

 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);
    }
}

.

编辑:我在 VS2012 中运行分析向导,我发现大部分时间都花在 RegEx.Match 函数上

4

2 回答 2

4

以下是一些想法:

  • 正则表达式匹配不是进行子字符串搜索的最有效方式,并且您对每个匹配的“类型”执行一次匹配检查。如果您需要匹配文字子字符串而不是模式,请查看有效的子字符串匹配算法,例如Boyer-Moore 。
  • 如果您必须使用 RegEx,请考虑使用已编译的表达式
  • 使用 BufferedStream 来提高 IO 性能。对于一个 6MB 的文件来说可能是微不足道的,但它只需要一行代码。
  • 使用分析器来确定确切的时间花费在哪里。
于 2013-03-07T20:52:29.203 回答
0

高层次的想法:

  1. 使用 Regex.Matches 一次查找所有匹配项,而不是一项一项。可能是主要性能受到打击

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

于 2013-03-07T20:56:44.003 回答