.net - .net 中的高性能文本文件解析

标签 .net performance optimization string

情况是这样的:

我正在制作一个小程序来解析服务器日志文件。

我用一个有几千个请求的日志文件测试了它(在 10000 到 20000 之间不确切知道)

我要做的是将日志文本文件加载到内存中,以便我可以查询它们。

这占用了最多的资源。

占用最多 cpu 时间的方法是那些(首先是最坏的罪魁祸首):

string.split - 将行值拆分为值数组

string.contains - 检查用户代理是否包含特定的代理字符串。 (确定浏览器ID)

string.tolower - 各种用途

streamreader.readline - 逐行读取日志文件。

string.startswith - 确定行是列定义行还是带有值的行

还有一些我可以替换的。例如字典 setter/getter 是 也占用了很多资源。这是我没想到的,因为它是一本字典,应该有它的键索引。我将其替换为多维数组并节省了一些 CPU 时间。

现在我在快速双核上运行,加载我提到的文件所需的总时间约为 1 秒。

现在这真的很糟糕。

想象一个每天有数万次访问的网站。加载日志文件需要几分钟时间。

那么我有什么选择呢?如果有的话,因为我认为这只是一个 .net 限制,我对此无能为力。

编辑:

如果你们中的某些专家想要查看代码并在此处找到问题,请查看我的代码文件:

到目前为止,占用资源最多的函数是 LogEntry.New 加载所有数据的函数称为Data.Load

创建的 LogEntry 对象总数:50 000。所用时间:0.9 - 1.0 秒。

CPU:amd phenom II x2 545 3ghz。

不是多线程

最佳答案

如果不查看您的代码,就很难知道您是否有任何错误会影响您的性能。如果没有看到一些样本数据,我们就无法合​​理地尝试实验来了解我们自己的表现。

你之前的字典键是什么?转移到多维数组听起来像是一个奇怪的举动 - 但我们需要更多信息才能知道您之前对数据做了什么。

请注意,除非您明确将工作并行化,否则拥有双核机器不会有任何不同。如果您真的受 CPU 限制,那么您可以并行化——尽管您需要小心地这样做;您很可能想要阅读文本的“ block ”(多行)并要求一个线程对其进行解析,而不是一次传递一行。不过,生成的代码可能会复杂得多。

老实说,我不知道 10,000 行一秒是否合理 - 如果您可以发布一些样本数据以及您需要用它做什么,我们可以提供更有用的反馈。

编辑:好的,我已经快速浏览了代码。一些想法...

最重要的是,这可能不是您应该“按需”执行的操作。相反,作为后台进程定期解析(例如,当日志滚动时)并将感兴趣的信息放入数据库中 - 然后在需要时查询该数据库。

但是,要优化解析过程:

  • 我个人不会一直检查 StreamReader 是否在末尾 - 只需调用 ReadLine 直到结果为 Nothing
  • 如果您希望“#fields”行排在第一位,请在循环外阅读它。这样您就不需要在每次迭代时都查看是否已经获得字段。
  • 如果您知道某行不为空,可能测试第一个字符是否为“#”可能比调用 line.StartsWith("#") - 我必须测试。
  • 每次您询问日期、时间、URI 主干或用户代理时,您都在扫描这些字段;相反,当您解析“#fields”行时,您可以创建一个新的 LineFormat 类的实例,它可以处理任何字段名称,但特别记住字段的索引你知道你会想要的。这也避免了为每个日志条目复制完整的字段列表,这是非常浪费的。
  • 当您拆分字符串时,您会获得比平常更多的信息:您知道预期有多少个字段,并且您知道您只拆分单个字符。您可能会为此编写一个优化版本。
  • 单独解析日期和时间字段然后组合结果可能比将它们连接起来然后解析更快。我必须对其进行测试。
  • 多维数组比一维数组慢得多。如果您确实想保持“复制每个条目的所有字段名称”的想法,则值得将其分成两个数组:一个用于字段,一个用于值。

可能还有其他事情,但恐怕我现在没有时间去深究:(

关于.net - .net 中的高性能文本文件解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2482157/

相关文章:

.net - WPF:使用 JPEG 压缩的 TIFF 图像?

c# - C# StreamWriter 的问题

c# - 在非 IE 浏览器中禁用 ASP.NET ImageButton

c# - 在这种情况下什么时候调用我的析构函数? (C#)

Python-在数组中创建唯一值的掩码

c# - IEnumerable<T>.Count 在哪些情况下进行了优化?

MySQL:为什么在优化表后复制到 tmp 表会更快

Javascript:{} 与 new Object() 性能

View 中的 SQL CTE 与存储过程中的临时表

algorithm - 如何找到字符串可能具有的对的最大值?