我有一个 PHP 脚本可以读取多个文件,我在 Windows 10 上运行它。当我第一次运行它时,它运行得很慢(几十秒),而下一次运行很快(不到一秒)。经过一段时间后(还不能说具体多少),问题重复出现,所以看起来涉及某种缓存。
为了缩小问题的范围,我添加了一些“手动分析”,发现有问题的是
fopen
(与之相比,flock
,fgets
不要花时间):
$profile_log = '';
$time = microtime(true);
// I'll remove the second line that presumably doesn't matter
// once I re-run the profiling and confirm that
$fileHandle = fopen($file_full_path_and_name, 'r');
if(!$fileHandle) return null;
$new_time = microtime(true);
$profile_log .= "open time: " . ($new_time - $time) . "\n";
$time = $new_time;
// ...
file_put_contents('./debug.txt', "$profile_log\n\n", FILE_APPEND);
为我的每个文件(大小在 600 KB - 10 MB 范围内)提供 0.7 秒或更多的“打开时间”。
可能出了什么问题,我该如何解决?
我也问过 AI 的建议,从它的回答来看,我想是这样的
Windows同时具有文件缓冲和缓存,
它由
fopen
调用(据我所知,这会导致预读整个文件而不是仅仅打开——而脚本只读取每个文件的第一行),
使用
$fileHandle = fopen($file_full_path_and_name, 'r', false, stream_context_create([
'options' => [
'write_buffer' => 0,
'read_buffer' => 0,
'buffer' => 0,
'flags' => FILE_FLAG_NO_BUFFERING,
]
]));
应该禁用它。
但是,上面的代码片段似乎并没有减少运行时间[TODO:再次重新测试]。
1-2-3 中哪些是正确的?任何其他想法如何处理这个问题或至少调试它?重现问题也有问题,因为我还不知道使缓存无效的方法。