I have a script in PHP that reads several files and I run it on Windows 10. When I run it for the first time, it works slowly (tens of seconds) and next times, it works quickly (less than a second). After some time elapses (can't say how much exactly yet), the problem repeats, so it looks like there's some kind of cache involved.
To narrow down the problem, I've added some "manual profiling" and found that the problematic bit is the fopen
(compared to it, flock
, fgets
take no time):
$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);
gives me "open time" of 0.7 seconds and more for each of my files (of the size in the range of 600 KB - 10 MB).
What could be wrong and how can I fix this?
I've also asked AI for suggestions and from what it replied I suppose that
Windows has both file buffering and caching,
it's invoked by
fopen
(as far as I understand, this causes pre-reading of the whole file instead of just opening – while the script reads just several first line of each file),using
$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, ] ]));
should disable that.
However, the above snippet doesn't seem to reduce the run time [TODO: retest once more].
Which of 1-2-3 are correct? Any other ideas how to deal with this issue or at least debug it? There's also a problem with reproducing the issue since I'm not aware yet of ways to invalidate the cache.
fopen
changes considerably – Pyle