diff options
author | Ruben Bridgewater <ruben@bridgewater.de> | 2019-04-03 02:58:31 +0200 |
---|---|---|
committer | Ruben Bridgewater <ruben@bridgewater.de> | 2019-04-07 11:28:15 +0200 |
commit | eb2d4161f56efa7d82a6364734c674757f1f3ea4 (patch) | |
tree | 192af123cb13b6e400d21cfe41496d4e116ffb8e /lib/internal/fs | |
parent | 97c0a3493529666e241277b199fca2d4e093121a (diff) | |
download | android-node-v8-eb2d4161f56efa7d82a6364734c674757f1f3ea4.tar.gz android-node-v8-eb2d4161f56efa7d82a6364734c674757f1f3ea4.tar.bz2 android-node-v8-eb2d4161f56efa7d82a6364734c674757f1f3ea4.zip |
fs: improve readFile performance
This increases the maximum buffer size per read to 512kb when using
`fs.readFile`. This is important to improve the read performance for
bigger files.
PR-URL: https://github.com/nodejs/node/pull/27063
Refs: https://github.com/nodejs/node/issues/25741
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jamie Davis <davisjam@vt.edu>
Diffstat (limited to 'lib/internal/fs')
-rw-r--r-- | lib/internal/fs/read_file_context.js | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/lib/internal/fs/read_file_context.js b/lib/internal/fs/read_file_context.js index a4e7a3563b..e1de8fc7cd 100644 --- a/lib/internal/fs/read_file_context.js +++ b/lib/internal/fs/read_file_context.js @@ -6,7 +6,14 @@ const { Buffer } = require('buffer'); const { FSReqCallback, close, read } = internalBinding('fs'); -const kReadFileBufferLength = 8 * 1024; +// Use 64kb in case the file type is not a regular file and thus do not know the +// actual file size. Increasing the value further results in more frequent over +// allocation for small files and consumes CPU time and memory that should be +// used else wise. +// Use up to 512kb per read otherwise to partition reading big files to prevent +// blocking other threads in case the available threads are all in use. +const kReadFileUnknownBufferLength = 64 * 1024; +const kReadFileBufferLength = 512 * 1024; function readFileAfterRead(err, bytesRead) { const context = this.context; @@ -14,19 +21,17 @@ function readFileAfterRead(err, bytesRead) { if (err) return context.close(err); - if (bytesRead === 0) - return context.close(); - context.pos += bytesRead; - if (context.size !== 0) { - if (context.pos === context.size) - context.close(); - else - context.read(); + if (context.pos === context.size || bytesRead === 0) { + context.close(); } else { - // Unknown size, just read until we don't get bytes. - context.buffers.push(context.buffer.slice(0, bytesRead)); + if (context.size === 0) { + // Unknown size, just read until we don't get bytes. + const buffer = bytesRead === kReadFileUnknownBufferLength ? + context.buffer : context.buffer.slice(0, bytesRead); + context.buffers.push(buffer); + } context.read(); } } @@ -60,7 +65,7 @@ class ReadFileContext { constructor(callback, encoding) { this.fd = undefined; this.isUserFd = undefined; - this.size = undefined; + this.size = 0; this.callback = callback; this.buffers = null; this.buffer = null; @@ -75,9 +80,10 @@ class ReadFileContext { let length; if (this.size === 0) { - buffer = this.buffer = Buffer.allocUnsafeSlow(kReadFileBufferLength); + buffer = Buffer.allocUnsafeSlow(kReadFileUnknownBufferLength); offset = 0; - length = kReadFileBufferLength; + length = kReadFileUnknownBufferLength; + this.buffer = buffer; } else { buffer = this.buffer; offset = this.pos; |