-
Notifications
You must be signed in to change notification settings - Fork 30k
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
fs: don't conflate data and callback in fs.appendFile #11607
Conversation
@seishun |
v4 is heading into maintenance mode in just over a week. We shouldn't need to worry about the inability to backport. The real concern, however, is that param defaults are not very optimized in v6 or v7. They likely won't see significant performance improvement until the new ignition toolchain lands in v8 5.9. @seishun ... have you benchmarked these changes at all? |
Never written benchmarks before, so I just copied readfile.js and changed read into write. Results:
No difference basically. |
Tried replacing the default argument with
@vsemozhetbyt can you comment? Maybe I'm doing something wrong. |
@vsemozhetbyt Yes, but your PR caused a performance degradation, and mine apparently doesn't. Which is what confuses me. |
The key thing with the benchmarks is that we don't want to see a significant loss. It's perfectly fine for things to remain the same :-) @seishun ... which versions were you comparing inn the benchmark runs above? I'd like to do a comparison run on my end |
@seishun That PR performance degradation was murky and I did not understand it. However, we changed things differently, so v8 may like your variant more than mine) |
@vsemozhetbyt I tried your variant too, but there was no difference. Now I'm more concerned about consistency. It seems we don't use default arguments anywhere in node.js, so maybe we shouldn't deviate from that here either. @nodejs/collaborators thoughts? Also, do we want to add this silly benchmark (last commit here)? |
@seishun Did you try with your benchmark or my ones (there are two there: with concurrent writes in the commit and with linear writes in this comment)? Maybe it is something wrong with my benchmarks. |
@vsemozhetbyt There's a difference with your benchmark. With a default argument:
With
The difference is that your benchmark doesn't wait for the callback, which I guess makes it less realistic than mine.
I compared master and this PR rebased on master. |
@seishun If I get it right, the benchmark with concurrent writes (in the commit) doesn't use callbacks, while the benchmark with linear writes (in this comment) does use callbacks. However, I had downgrade with both( |
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.
fs
change lgtm
If it benchmarks okay (which it seems to by now?) I’m in favour of using default arguments, most of the time it increases readability. |
Default arguments seem to have improved significantly recently but I'd would still likely avoid them in hot code for a bit longer. |
Also keep in mind that there are other side effects... Such as the 'length' property of the function not counting params with defaults. |
How can we proceed with this fix? |
Ahum, I'm slightly towards -1 on this. Not because of the change in itself, but because writeFile requires data to be a string, a buffer or a uint8array. I think we should check that, and throw an error if that's not the case. |
Please provide a test case that isn't fixed by this PR. |
To me, > fs.writeFile('foo', console.log)
undefined
> (node:13028) [DEP0013] DeprecationWarning: Calling an asynchronous function without callback is deprecated. Should throw because of a missing data object, not give a warning because of a missing callback. The missing callback warning should still be there, in case we call |
@mcollina It's true that node allows you to specify any value as
But I think it's a separate issue, and it's not clear cut whether we want to be more strict about it. |
The problem in: > fs.writeFile('foo', console.log)
undefined
> (node:13028) [DEP0013] DeprecationWarning: Calling an asynchronous function without callback is deprecated. is that |
This automatic conversion goes way back to fa829b0 and nodejs/node-v0.x-archive#657. I'm not sure if it's something worth changing at this point. @nodejs/collaborators opinions? |
benchmark/fs/writefile.js
Outdated
@@ -0,0 +1,44 @@ | |||
// Call fs.writeFile over and over again really fast. | |||
// Then see how many times it got called. | |||
// Yes, this is a silly benchmark. Most benchmarks are silly. |
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.
😸
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 very thought out suggestion]
Maybe count bytes?
If I understand this correctly this is supposed to benchmarks node
mechanics not the OS, so number of runs would be my intuition too, but then there is weak correlation between the len
arg to the results.
If you count bytes, the number of runs can be deduced by calculating result / len
, so we don't lose information, and it might be easier to see the ratio of node time / OS time
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.
I'd prefer to just not add this benchmark TBH. I only added it to demonstrate that default arguments don't cause performance regressions, but I'm not using them anymore. I should have just gisted it instead I guess.
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.
Also a valid option IMHO
Since this asserts https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback I think an |
@refack what test case exactly? It doesn't introduce any new exceptions. |
Added a test, PTAL. |
The failures seem unrelated? |
OSX - known #13559 freeBSD - parallel/test-process-external-stdio-close |
freeBSD was a flake - #13586 |
PR-URL: #11607 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
PR-URL: #11607 Reviewed-By: Roman Reiss <me@silverwind.io> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Should this be backported to v6.x? |
If #12456 was backported, then this should be too. |
Fixes #11595.
Before:
After:
Will add a test if there are no objections to the fix.
Suggestions regarding the commit message are welcome.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
fs