gpt4 book ai didi

optimization - 通用 Lisp : Optimizing file parsing for minimum reads and memory allocations

转载 作者:行者123 更新时间:2023-12-03 17:23:19 25 4
gpt4 key购买 nike

我可以使用一些帮助来优化一些 Common Lisp 代码。我正在尝试从日志文件中查询数据。从超过 14.5 万行中拉出前 50 行需要一秒钟的时间。推断出来,仅从日志文件中读取数据就需要将近 5 分钟。此外,当整个文件只有 14MB 时,我当前实现的前 50 行分配了约 50MB。我想要去的地方是对数据执行 1 次读取,以使用最少的内存分配来解析它。

我知道我看到的性能下降是由于我的代码。我很难思考的是如何重构我的代码以最大限度地减少我所看到的问题。我尝试使用 WITH-INPUT-FROM-STRING 将字符串作为流访问,但性能没有明显变化。

这是一个 IIS 日志,因此它将具有一致的结构。前 2 个字段是日期和时间,我想将其解析为一个数字,以便在需要时限制数据范围。之后,大多数字段的大小将是可变的,但所有字段都用空格分隔。

使用我的代码:使用 8 个可用 CPU 内核运行需要 1,138,000 微秒(1.138000 秒)。
在此期间,用户模式花费了 1,138,807 微秒(1.138807 秒)
在系统模式下花费了 0 微秒(0.000000 秒)
GC 花费了 19,004 微秒(0.019004 秒)。
分配了 49,249,040 字节的内存。

没有我的代码:使用 8 个可用 CPU 内核运行需要 64,000 微秒(0.064000 秒)。
在此期间,用户模式花费了 62,401 微秒(0.062401 秒)
在系统模式下花费了 0 微秒(0.000000 秒)
分配了 834,512 字节的内存。

(defun read-date-time (hit)
(let ((date-time (chronicity:parse (subseq hit 0 20))))
(encode-universal-time (chronicity:sec-of date-time)
(chronicity:minute-of date-time)
(chronicity:hour-of date-time)
(chronicity:day-of date-time)
(chronicity:month-of date-time)
(chronicity:year-of date-time))))

(defun parse-hit (hit)
(unless (eq hit :eof)
(cons (read-date-time hit)
(split-sequence:split-sequence #\Space (subseq hit 20)))))


(time (gzip-stream:with-open-gzip-file (ins "C:\\temp\\test.log.gz")
(read-line ins nil :eof)
(loop for i upto 50
do (parse-hit (read-line ins nil :eof)))))

我的第一次尝试是一种非常幼稚的方法,我认识到我的代码现在可以使用一些改进,所以我要求一些方向。如果教程更适合回答这个问题,请发布链接。我喜欢

最佳答案

问题是 Chronicity 包,它在内部使用了 Local Time 包。

这个:

   (encode-universal-time (chronicity:sec-of date-time)
(chronicity:minute-of date-time)
(chronicity:hour-of date-time)
(chronicity:day-of date-time)
(chronicity:month-of date-time)
(chronicity:year-of date-time))))

正在粉碎你。
chronicity:month-of电话 local-time:timestamp-month .如果你看一下它的代码:
 (nth-value 1
(%timestamp-decode-date
(nth-value 1 (%adjust-to-timezone timestamp timezone))))

所以,这是解码基本日期(似乎是一个整数),两次,(一次是时区,一次是月份。

所以你解码同一个日期,做同样的工作,每个日期 6 次。而这些例行公事正在掀起一场 Storm 。

您还调用了 subseq 两次。

所以,在我看来,在这种情况下你需要专注于日期解析逻辑,使用不那么通用的东西。您不必验证日期(假设日志是准确的),并且您不需要转换为自纪元以来的天/秒/毫秒,您只需要单独的 MDY、HMS 数据。您正在使用当前包完成所有这些工作,一旦您创建了通用时间,它就变得多余了。

您也可能不关心时区。

无论如何,这是问题所在的开始。这还不是 I/O 问题。

关于optimization - 通用 Lisp : Optimizing file parsing for minimum reads and memory allocations,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19471170/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com