[HN Gopher] fs.promises.readFile is 40% slower than fs.readFile
       ___________________________________________________________________
        
       fs.promises.readFile is 40% slower than fs.readFile
        
       Author : Jarred
       Score  : 29 points
       Date   : 2021-03-03 18:54 UTC (4 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | beaconstudios wrote:
       | const readFilePromise = (...args) => new Promise((resolve,
       | reject) => readFile(...args, (err, result) => err ? reject(err) :
       | resolve(result)))
       | 
       | How can the native implementation be much more complex than that,
       | beyond maybe some argument assertions? That will take almost the
       | exact same amount of time as readFile, the additional time cost
       | is a small constant value.
        
         | Jarred wrote:
         | I agree in principle, but for some reason, the underlying
         | implementation for fs.promises is completely separate.
         | 
         | I think this is where fs.promises.readFile reads the actual
         | file https://github.com/nodejs/node/blob/master/lib/internal/fs
         | /p..., with many layers of indirection before that
         | 
         | fs.readFile is this one function:
         | https://github.com/nodejs/node/blob/master/lib/fs.js#L327-L3...
        
         | idbehold wrote:
         | I believe the difference here is that these newly introduced
         | promise wrappers allow you to pass an AbortSignal instances to
         | them. Wrapping the old callback style methods would not allow
         | you to "abort" in the middle of reading a file. You could
         | respond to a passed in AbortSignal instance in the simple
         | `readFilePromise` function you provided by simply rejecting
         | early, but it wouldn't free up the underlying file descriptor
         | until after the entire file had been read.
        
         | orf wrote:
         | On a SSD reading files is fast. However read() is a blocking
         | operation that _could_ take forever - reading some  /dev/
         | device that never returns any data, or a slower medium that
         | takes hundreds of milliseconds per read. That's a big no-no. So
         | it gets dispatched to a dedicated blocking-io threadpool with
         | limited workers which does the blocking operation without
         | interrupting the event loop.
         | 
         | I'm guessing as disk speeds have increased the relative
         | overhead of dispatching the task to a thread pool has also
         | increased.
         | 
         | At least, that's how I think it works based on some half-
         | remembered blog post.
         | 
         | Edit: yep - http://docs.libuv.org/en/v1.x/design.html#file-i-o
        
           | beaconstudios wrote:
           | I can fully believe that there's some cleverness going on
           | with node file I/O - but there should be no meaningful
           | difference in performance between returning the result via a
           | Promise, versus a callback.
        
             | orf wrote:
             | It depends - I would assume the callback pattern is much
             | easier to JIT than the promise pattern and requires less
             | objects to be allocated, but you're right. That's a huge
             | difference.
             | 
             | You'd need to benchmark another non-io bound function to
             | find how much overhead comes from promises themselves.
        
               | beaconstudios wrote:
               | Not enough to add 40% overhead to a 1mb file read, I can
               | tell you that much.
        
           | hinkley wrote:
           | Network filesystems, compressed filesystems, and of course
           | the ever-dreaded on-access virus scanners on Windows that
           | 'break' one open source project after another. Who knew that
           | opening the same file 10 times is slow? Everybody. Everybody
           | knew that.
           | 
           | Looking at you, svn team.
        
       | xiphias2 wrote:
       | What really disturbs me is this comment:
       | 
       | ,,But no one said fs.promises.readFile should perform similarly
       | to fs.readFile ''
       | 
       | I'm happy that it was downvoted at least, but there should be a
       | better way to set expectations for excellence in development.
        
         | arghwhat wrote:
         | I fear that the individual might even be serious...
        
           | ncallaway wrote:
           | It seemed pretty clear that it's a joke to me, with the
           | thinky-face emoji after it, but that's just my reading of it.
        
         | CyberRabbi wrote:
         | Well his point is this technically isn't a bug because
         | comparable performance to fs.readFile was never guaranteed as
         | part of the API contract. I don't think his statement implies
         | we generally ought not to expect excellence nor that effort
         | shouldn't be spent on improving things.
         | 
         | I think his point is valid even if slightly tongue in cheek.
         | Bugs are defined by the contract / specification not wishful
         | thinking.
        
       ___________________________________________________________________
       (page generated 2021-03-03 23:01 UTC)