-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
perf(runtime/fs): optimize readFile by using a single large buffer #12057
Conversation
Accidentally committed, denoland#12056 adds `read_128k_sync`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not in favor of this. File reads area not atomic. We can't start optimizing at the cost of correctness.
My point is more that there's no sane use-case to write & read-all at the same time when you don't control the rate of reading and it's uncommon and IMO would be mostly fine as is. But as I mentioned we can make this more robust:
essentially the current implementation would be a fast path for an unchanged file and then it would fallback to the slow path if the file was extended, so that wouldn't hurt or change correctness |
With fallback, SGTM |
FWIW, node.js does exactly this. https://github.com/nodejs/node/blob/bbd4c6eee90ef600022c72316ba82d37a2ae16bc/lib/fs.js#L326-L349 |
Allocate an extra byte in our read buffer to detect "overflow" then fallback to unsized readAll for remainder of extended file, this is a slowpath that should rarely happen in practice
I still think that it would be sane/fair to not read beyond the stat'd size, I can't imagine a sane use-case for it but I implemented the slowpath fallback anyway. @bartlomieju @lucacasonato That should address your concerns |
if (cursor > size) { | ||
// Read remaining and concat | ||
return concatBuffers([buf, readAllSync(r)]); | ||
} else { // cursor == size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} else { // cursor == size | |
} else { // cursor <= size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This avoids allocating N buffers when reading entire files and copying when concatenating them.
Benchmarks
Notes
read_128k_sync
are somewhat reduced here by the extra cwd lookups caused by thestat
, so perf(runtime): cache cwd lookups #12056 will work hand in hand with this change to improve file readsreadTextFile
/readTextFileSync