| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
Have you ran the existing statSync() benchmarks to compare before and after this change? |
Sorry, something went wrong.
a nodejs issue causes certain dates to be off by 1ms after calling utimes See: nodejs/node#12607
Sorry, something went wrong.
|
From a CI log: ../src/node_file.cc: In function ‘void node::FillStatsArray(double*, const uv_stat_t*)’: ../src/node_file.cc:469:121: error: ‘round’ was not declared in this scope X(10, atim) |
Sorry, something went wrong.
|
Mmm needs to include math for linux, had only built on Windows. |
Sorry, something went wrong.
Sorry, something went wrong.
|
Linux benchmark results: jdp@vrt:~/node$ cat c.csv | Rscript benchmark/compare.R
improvement confidence p.value
fs/bench-statSync.js kind="fstatSync" n=1000000 -2.21 % ** 0.004221974
fs/bench-statSync.js kind="lstatSync" n=1000000 -1.09 % 0.146230478
fs/bench-statSync.js kind="statSync" n=1000000 0.67 % 0.415415495
Windows benchmark results: C:\dev\node>Rscript benchmark\compare.R <c.csv
improvement confidence p.value
fs\\bench-statSync.js kind="fstatSync" n=1000000 -1.50 % ** 1.763399e-03
fs\\bench-statSync.js kind="lstatSync" n=1000000 -2.36 % *** 3.457501e-06
fs\\bench-statSync.js kind="statSync" n=1000000 -0.77 % 2.111487e-01
Pretty substantial hit. Especially for linux considering it can't even have sub-ms filetimes. |
Sorry, something went wrong.
|
@refack How does uv_uptime relate to this? |
Sorry, something went wrong.
🤦I was half asleep. |
Sorry, something went wrong.
|
To rectify my half-baked-sleepy-thought from before, let me suggest a different solution: lib/fs.js | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/lib/fs.js b/lib/fs.js
index c1d8db9f8..8759dcf83 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -157,10 +157,14 @@ function Stats(
this.ino = ino;
this.size = size;
this.blocks = blocks;
- this.atime = new Date(atim_msec);
- this.mtime = new Date(mtim_msec);
- this.ctime = new Date(ctim_msec);
- this.birthtime = new Date(birthtim_msec);
+ Object.defineProperties(fs, {
+ atime: {enumerable: true, get() {return new Date(Math.Round(atim_msec))}},
+ mtime: {enumerable: true, get() {return new Date(Math.Round(mtim_msec))}},
+ ctime: {enumerable: true, get() {return new Date(Math.Round(ctim_msec))}},
+ birthtime: {enumerable: true, get() {
+ return new Date(Math.Round(birthtim_msec))
+ }}
+ }
}
fs.Stats = Stats; |
Sorry, something went wrong.
|
Also there's the Truncate(x + 0.5) trick that might be more performant FYI on windows the values are only accurate to 0.1 millisecond
|
Sorry, something went wrong.
There was a problem hiding this comment.
I'm not a C++ maven but maybe
(static_cast<double>((s->st_##name.tv_nsec + 500000) / 1000000))
Would be faster
Also If you're already here could you #define the magic numbers please?
Sorry, something went wrong.
|
@refack yeah truncating and adding 0.5ms is another option. felt a bit ugly to suggest but it would fix the issue with likely lower impact on performance. rounding seems like the more correct approach, but considering the slowdown it is worth considering trunc+add. i'm not too sure that using lazy properties on the stat object would be good.. i did consider it, but it's a bit unexpected that reading time values after stat finishes involves a function call. might not really matter, though. |
Sorry, something went wrong.
|
AFAIK the only issue with adding 0.5 and dividing would be if the value was negative, but since that should/will never be the case here, it may be safe to do. It would be interesting to see the performance difference anyway compared to just round(). |
Sorry, something went wrong.
|
In hot spots we generally prefer performance over "the most correct solution" |
Sorry, something went wrong.
name.tv_nsec is an unsigned long 👍 |
Sorry, something went wrong.
There is/was previous discussion about these kinds of changes to fs.Stats in another thread. |
Sorry, something went wrong.
@mscdex couldn't find anything recent about the times... Do you remember where? |
Sorry, something went wrong.
Sorry, something went wrong.
|
I'll try to run some more benchmarks tomorrow. Been up for a few days now, getting tired.. If we're looking into the lazy prop approach i'd expect to have to define them once on the prototype rather than in the constructor, as defineProperty is plenty more expensive than instantiating a Date. To do that we'll need a way to get the msec times outside the constructor, and also the return values should likely be cached in get(). I can give it a look when i have a little time to see what effect it would have. |
Sorry, something went wrong.
Yes on all 👍 |
Sorry, something went wrong.
|
The define in the ctor allowed me to hide them in a closure, but you could store the raw numbers in _XXXX members and answer #8276 |
Sorry, something went wrong.
a nodejs issue causes certain dates to be off by 1ms after calling utimes See: nodejs/node#12607
This also reverts commit 9836cf5. Fixes: npm/npm#16734 Ref: nodejs#12607 Ref: nodejs#12818
* convert ’ to ' to turn md file to ASCII Fixes: nodejs#8276 Refs: nodejs#12607 Refs: nodejs#12818 Refs: nodejs#13256
PR-URL: nodejs#13173 Fixes: nodejs#8276 Refs: nodejs#12607 Refs: nodejs#12818 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Brian White <mscdex@mscdex.net>
|
Should this land on v6.x? |
Sorry, something went wrong.
Yes
|
Sorry, something went wrong.
|
This is not landing cleanly, would you be willing to do a backport with the commits you mention? |
Sorry, something went wrong.
|
ping |
Sorry, something went wrong.
a nodejs issue causes certain dates to be off by 1ms after calling utimes See: nodejs/node#12607
| Back | FazBrowse Home | New Git URL |
Truncation of submillisecond timestamp accuracy on windows creates situations where attempting to change access or modification times becomes off by one ms. Example:
This PR fixes the issue by rounding nsec rather than truncating in node_file.cc. A concern with that is that stat is a rather hot bit of code.. adding in 4 rounding operations could make a noticeable difference.
Another option could be to increment the return from toUnixTimestamp in fs.js enough to offset the precision loss, that would at least fix the issue if only node processes are updating the files.. but not particularly robust.
A third solution is to ignore the problem. It likely isn't something that affects that many users.
Checklist
Affected core subsystem(s)
src