【发布时间】:2011-09-26 21:10:01
【问题描述】:
我在测试我编写的代码时注意到的一点是,长时间运行的操作往往在第一次运行程序时比在后续运行时运行更多,有时是 10 倍或更多的。显然这里存在某种冷缓存/热缓存问题,但我似乎无法弄清楚它是什么。
这不是 CPU 缓存,因为这些长时间运行的操作往往是我向其中提供大量数据的循环,并且它们应该在第一次迭代后完全加载。 (另外,卸载和重新加载程序应该会清除缓存。)
另外,它不是磁盘缓存。我已经通过预先从磁盘加载所有数据并在之后进行处理来排除这种情况,而实际的 CPU 密集型数据处理速度很慢。
那么是什么导致我的程序在我第一次运行时运行缓慢,但如果我关闭它并再次运行它,它的运行速度会大大加快?我在几个不同的程序中看到了这一点,它们做的事情非常不同,所以这似乎是一个普遍的问题。
编辑:为澄清起见,我正在用 Delphi 编写,但我并不认为这是特定于 Delphi 的问题。但这意味着无论问题是什么,它都与 JIT 问题、垃圾收集问题或托管代码带来的任何其他包袱无关。而且我不是在处理网络连接。这是纯 CPU 密集型处理。
一个例子:一个脚本编译器。它是这样运行的:
- 将整个文件从磁盘加载到内存中
- 将整个文件编入令牌队列
- 将队列解析成树
- 在树上运行 codegen 以生成字节码
如果我在将整个内容从磁盘加载到内存后为其提供一个巨大的脚本文件(约 100k 行),则第一次运行时 lex 步骤大约需要 15 秒,后续运行需要 2 秒。 (是的,我知道这还有很长的时间。我正在努力解决这个问题......)我想知道这种放缓来自哪里以及我能做些什么。
【问题讨论】:
-
你确定不是I/O缓存?对我来说,这听起来像是操作系统的 I/O 缓存层。 CPU 计算没有缓存,所以它必须在某处存储...
-
@David 查看第一个答案以获取反例。我可以为其他语言添加更多内容。不要假设。
-
需要 15 秒来对存储在内存中的 100 kb 文件进行 lex 处理,这非常长。先找出它为什么这么慢,然后再弹出它更快的原因。顺便说一句,注意页面错误。
-
三个想法:1)病毒扫描程序? 2)您是否尝试过在没有 IDE 的情况下运行可执行文件? 3) 你是否使用了一些可能只在第一次加载的 DLL?
-
Gamecats 病毒扫描点是一个非常好的。许多病毒扫描程序只会在应用程序第一次运行时对其进行全面检查。其他时候,他们可能只是对文件进行哈希检查以确认它没有被更改。 @Gamecat - 你应该把它放在一个答案中。
标签: windows performance delphi caching