-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
dns: refactor internal/dns/promises.js #27081
Conversation
Use `isIP()` instead of `isIPv4()` since it does the additional functionality that we were adding after our calls to `isIP()`. This not-so-incidentally also increases code coverage from tests. At least one of the replaced ternaries was difficult to cover reliably because operating system/configuration variances were too unpredictable.
FWIW |
Yeah, I guess it's worth noting that, at least in theory, this can change the behavior. Previously, anything that wasn't IPv4 was automatically deemed IPv6. Now we're actually checking that the address is a legit IPv6, and if it's not, family will be
Both of these are in callbacks for https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/318/ |
https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/319/ |
Results seem OK to me so far. Will try with a larger 'N' to see if we can get something statistically significant. 18:13:55 confidence improvement accuracy (*) (**) (***)
18:13:55 dns/lookup.js n=5000000 all='false' name='' -0.06 % ±2.95% ±3.93% ±5.11%
18:13:55 dns/lookup.js n=5000000 all='false' name='::1' -0.83 % ±1.75% ±2.32% ±3.02%
18:13:55 dns/lookup.js n=5000000 all='false' name='127.0.0.1' -0.30 % ±2.04% ±2.71% ±3.53%
18:13:55 dns/lookup.js n=5000000 all='true' name='' -1.08 % ±2.92% ±3.89% ±5.07%
18:13:55 dns/lookup.js n=5000000 all='true' name='::1' -0.74 % ±2.79% ±3.74% ±4.93%
18:13:55 dns/lookup.js n=5000000 all='true' name='127.0.0.1' -0.50 % ±4.57% ±6.09% ±7.93%
18:13:55
18:13:55 Be aware that when doing many comparisons the risk of a false-positive
18:13:55 result increases. In this case there are 6 comparisons, you can thus
18:13:55 expect the following amount of false-positive results:
18:13:55 0.30 false positives, when considering a 5% risk acceptance (*, **, ***),
18:13:55 0.06 false positives, when considering a 1% risk acceptance (**, ***),
18:13:55 0.01 false positives, when considering a 0.1% risk acceptance (***)
18:13:56 ++ mv output040419-020556.csv /w/bnch-comp |
https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/320/ (Same as previous run but bumping the number of times we run each benchmark up from 30 to 128 in the hopes of getting some statistically significant results. Alternatively, if we see some results that show this PR being faster, it will be more obvious that this is a wash.) |
Hmmm.... 22:21:41 ++ Rscript benchmark/compare.R
22:21:41 confidence improvement accuracy (*) (**) (***)
22:21:41 dns/lookup.js n=5000000 all='false' name='' 0.24 % ±1.51% ±1.98% ±2.55%
22:21:41 dns/lookup.js n=5000000 all='false' name='::1' 0.62 % ±0.91% ±1.20% ±1.54%
22:21:41 dns/lookup.js n=5000000 all='false' name='127.0.0.1' *** -4.38 % ±1.66% ±2.19% ±2.81%
22:21:41 dns/lookup.js n=5000000 all='true' name='' 1.02 % ±1.72% ±2.27% ±2.91%
22:21:41 dns/lookup.js n=5000000 all='true' name='::1' -0.00 % ±1.08% ±1.42% ±1.82%
22:21:41 dns/lookup.js n=5000000 all='true' name='127.0.0.1' -0.55 % ±1.97% ±2.60% ±3.33%
22:21:41
22:21:41 Be aware that when doing many comparisons the risk of a false-positive
22:21:41 result increases. In this case there are 6 comparisons, you can thus
22:21:41 expect the following amount of false-positive results:
22:21:41 0.30 false positives, when considering a 5% risk acceptance (*, **, ***),
22:21:41 0.06 false positives, when considering a 1% risk acceptance (**, ***),
22:21:41 0.01 false positives, when considering a 0.1% risk acceptance (***) |
Running again for confirmation: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/321/ |
It occurs to me that the benchmark probably isn't actually testing the code touched by this PR as it tests the non-promise version of Having said that, there is similar code in Line 63 in a3cf96c
Line 78 in a3cf96c
|
You sure the current benchmark isn't affected by this change already?: 23:26:01 confidence improvement accuracy (*) (**) (***)
23:26:01 dns/lookup.js n=5000000 all='false' name='' 0.12 % ±1.55% ±2.04% ±2.62%
23:26:01 dns/lookup.js n=5000000 all='false' name='::1' -0.15 % ±1.05% ±1.39% ±1.78%
23:26:01 dns/lookup.js n=5000000 all='false' name='127.0.0.1' *** -2.44 % ±1.27% ±1.68% ±2.15%
23:26:01 dns/lookup.js n=5000000 all='true' name='' -0.39 % ±1.80% ±2.37% ±3.04%
23:26:01 dns/lookup.js n=5000000 all='true' name='::1' -0.12 % ±1.44% ±1.90% ±2.44%
23:26:01 dns/lookup.js n=5000000 all='true' name='127.0.0.1' -0.36 % ±2.02% ±2.66% ±3.41%
23:26:01
23:26:01 Be aware that when doing many comparisons the risk of a false-positive
23:26:01 result increases. In this case there are 6 comparisons, you can thus
23:26:01 expect the following amount of false-positive results:
23:26:01 0.30 false positives, when considering a 5% risk acceptance (*, **, ***),
23:26:01 0.06 false positives, when considering a 1% risk acceptance (**, ***),
23:26:01 0.01 false positives, when considering a 0.1% risk acceptance (***) |
(I agree that it doesn't make sense. But at the same time, the results are consistent. Something's up.) |
@Trott this looks like statistical anomalies to me. |
Yes. At least according to coverage: -bash-4.2$ rm -rf out/Release/.coverage/
-bash-4.2$ NODE_V8_COVERAGE=out/Release/.coverage tools/test.py test/benchmark/test-benchmark-dns.js
[00:00|% 100|+ 1|- 0]: Done
-bash-4.2$ grep -oP '[\w/.]*dns[\w/.]*' out/Release/.coverage/*
out/Release/.coverage/coverage-43652-1554392808703-0.json:dns.js
out/Release/.coverage/coverage-43666-1554392808663-0.json:///home/users/riclau/sandbox/github/nodejs/benchmark/dns/lookup.js
out/Release/.coverage/coverage-43666-1554392808663-0.json:dns.js
out/Release/.coverage/coverage-43666-1554392808663-0.json:internal/dns/utils.js
out/Release/.coverage/coverage-43676-1554392808645-0.json:///home/users/riclau/sandbox/github/nodejs/benchmark/dns/lookup.js
out/Release/.coverage/coverage-43676-1554392808645-0.json:dns.js
out/Release/.coverage/coverage-43676-1554392808645-0.json:internal/dns/utils.js
-bash-4.2$ |
But the results are consistent. Twice now, the same one has a very high degree of confidence (low p-value). While it all-but-certainly isn't a reflection of the code change, it is (almost certainly) a reflection of something. An artifact somewhere. Maybe with this benchmark, and the way the operating system caches lookups, the second benchmark will always be slower? In other words, maybe the benchmark doesn't yield valid results ever, at least on the OS where we're running it? Let's test that theory: Here's a run with no code changes. (The PR is a change to a GOVERNANCE.md only, so the code source should be identical.) https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/322/ |
Ah, there we go, the benchmark is clearly not providing valid results. Same code shows statistically significant differences in performance: 10:02:54 ++ Rscript benchmark/compare.R
10:02:54 confidence improvement accuracy (*) (**) (***)
10:02:54 dns/lookup.js n=5000000 all='false' name='' 0.67 % ±1.50% ±1.98% ±2.54%
10:02:54 dns/lookup.js n=5000000 all='false' name='::1' 0.90 % ±1.08% ±1.42% ±1.82%
10:02:54 dns/lookup.js n=5000000 all='false' name='127.0.0.1' ** -1.97 % ±1.23% ±1.62% ±2.08%
10:02:54 dns/lookup.js n=5000000 all='true' name='' 1.17 % ±1.68% ±2.22% ±2.84%
10:02:54 dns/lookup.js n=5000000 all='true' name='::1' 0.29 % ±1.00% ±1.32% ±1.70%
10:02:54 dns/lookup.js n=5000000 all='true' name='127.0.0.1' -0.82 % ±2.01% ±2.65% ±3.40%
10:02:54
10:02:54 Be aware that when doing many comparisons the risk of a false-positive
10:02:54 result increases. In this case there are 6 comparisons, you can thus
10:02:54 expect the following amount of false-positive results:
10:02:54 0.30 false positives, when considering a 5% risk acceptance (*, **, ***),
10:02:54 0.06 false positives, when considering a 1% risk acceptance (**, ***),
10:02:54 0.01 false positives, when considering a 0.1% risk acceptance (***) |
The benchmarks for dns.lookup() include calling it with an empty hostname which results in a deprecation warning. This benchmark seems to be subject to some odd side effects (see Ref below) and we probably generally don't want to benchmark deprecated things by default anyway. Remove the deprecated value from the default list. Bonus is that this will speed up the benchmark. Refs: nodejs#27081 (comment)
The benchmarks for dns.lookup() include calling it with an empty hostname which results in a deprecation warning. This benchmark seems to be subject to some odd side effects (see Ref below) and we probably generally don't want to benchmark deprecated things by default anyway. Remove the deprecated value from the default list. Bonus is that this will speed up the benchmark. Refs: nodejs#27081 (comment) PR-URL: nodejs#27091 Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
OK, the benchmark has been modified slightly, so let's see if we no longer get the false positive on a running-the-same-version-of-node-for-both-benchmarks: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/326/ And, in an optimistic move, let's re-run the benchmark for this PR: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/327/ (scheduled) If that doesn't have surprising results, then I suppose the next step is to write a benchmark for DNS promises and to add the |
Still seeing the false positive in the benchmark run using the same executable: 23:14:21 confidence improvement accuracy (*) (**) (***)
23:14:21 dns/lookup.js n=5000000 all='false' name='::1' 0.46 % ±0.85% ±1.13% ±1.45%
23:14:21 dns/lookup.js n=5000000 all='false' name='127.0.0.1' * -1.83 % ±1.66% ±2.18% ±2.80%
23:14:21 dns/lookup.js n=5000000 all='true' name='::1' -0.44 % ±0.96% ±1.26% ±1.62%
23:14:21 dns/lookup.js n=5000000 all='true' name='127.0.0.1' 0.49 % ±2.19% ±2.88% ±3.70%
23:14:21
23:14:21 Be aware that when doing many comparisons the risk of a false-positive
23:14:21 result increases. In this case there are 4 comparisons, you can thus
23:14:21 expect the following amount of false-positive results:
23:14:21 0.20 false positives, when considering a 5% risk acceptance (*, **, ***),
23:14:21 0.04 false positives, when considering a 1% risk acceptance (**, ***),
23:14:21 0.00 false positives, when considering a 0.1% risk acceptance (***) |
@Trott if you change the cases mentioned here #27081 (comment) and then restart the benchmark, it'll execute changed code in the expected way. So the outcome should also be more significant. One star as confidence is mostly a statistical anomaly. Yes, there were also three stars with a low percentage value but even that happens from time to time. |
Running this change with the benchmark file in #27249 resulted in no statistically-significant difference in performance. I think this is good to land. $ cat /var/tmp/trott | Rscript benchmark/compare.R
confidence improvement accuracy (*) (**) (***)
dns/lookup-promises.js n=5000000 all='false' name='::1' 0.63 % ±3.40% ±4.53% ±5.90%
dns/lookup-promises.js n=5000000 all='false' name='127.0.0.1' -1.68 % ±2.72% ±3.63% ±4.74%
dns/lookup-promises.js n=5000000 all='true' name='::1' -0.47 % ±2.32% ±3.10% ±4.04%
dns/lookup-promises.js n=5000000 all='true' name='127.0.0.1' 2.53 % ±3.48% ±4.64% ±6.08%
dns/lookup.js n=5000000 all='false' name='::1' 0.56 % ±3.38% ±4.50% ±5.85%
dns/lookup.js n=5000000 all='false' name='127.0.0.1' 2.14 % ±4.92% ±6.55% ±8.54%
dns/lookup.js n=5000000 all='true' name='::1' 2.47 % ±3.17% ±4.22% ±5.51%
dns/lookup.js n=5000000 all='true' name='127.0.0.1' -0.96 % ±4.11% ±5.47% ±7.12%
Be aware that when doing many comparisons the risk of a false-positive
result increases. In this case there are 8 comparisons, you can thus
expect the following amount of false-positive results:
0.40 false positives, when considering a 5% risk acceptance (*, **, ***),
0.08 false positives, when considering a 1% risk acceptance (**, ***),
0.01 false positives, when considering a 0.1% risk acceptance (***)
$ |
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.
@Trott it would be good to actually have a consistent handling across the "regular" dns functions and the promise based ones as pointed out here #27081 (comment). Please do not land this for promises only.
Done. A re-review or two would be good. @jasnell @lpinca @richardlau @BridgeAR |
In lib/dns.js, use `isIP()` instead of `isIPv4()` for determining the `family` property in `lookup()`. If an invalid IP address is returned, the `family` currently provided is `6`. With this change, it will be `0`. Update documentation to reflect this.
9670302
to
d3c7421
Compare
Additional benchmark for the callback-based changes. Might not actually be relevant to the change here, but hey, for completeness.... confidence improvement accuracy (*) (**) (***)
dns/lookup.js n=5000000 all='false' name='::1' -1.36 % ±2.45% ±3.27% ±4.25%
dns/lookup.js n=5000000 all='false' name='127.0.0.1' 2.22 % ±3.62% ±4.81% ±6.27%
dns/lookup.js n=5000000 all='true' name='::1' 1.37 % ±3.38% ±4.51% ±5.90%
dns/lookup.js n=5000000 all='true' name='127.0.0.1' 2.94 % ±7.22% ±9.61% ±12.51%
Be aware that when doing many comparisons the risk of a false-positive
result increases. In this case there are 4 comparisons, you can thus
expect the following amount of false-positive results:
0.20 false positives, when considering a 5% risk acceptance (*, **, ***),
0.04 false positives, when considering a 1% risk acceptance (**, ***),
0.00 false positives, when considering a 0.1% risk acceptance (***) |
Landed in 14df42f...09cdc37 |
Use `isIP()` instead of `isIPv4()` since it does the additional functionality that we were adding after our calls to `isIP()`. This not-so-incidentally also increases code coverage from tests. At least one of the replaced ternaries was difficult to cover reliably because operating system/configuration variances were too unpredictable. PR-URL: nodejs#27081 Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
In lib/dns.js, use `isIP()` instead of `isIPv4()` for determining the `family` property in `lookup()`. If an invalid IP address is returned, the `family` currently provided is `6`. With this change, it will be `0`. Update documentation to reflect this. PR-URL: nodejs#27081 Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
Adding this benchmark will let us check the performance implications of nodejs#27081.
Adding this benchmark will let us check the performance implications of nodejs#27081. PR-URL: nodejs#27249 Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Yongsheng Zhang <[email protected]>
Use
isIP()
instead ofisIPv4()
since it does the additionalfunctionality that we were adding after our calls to
isIP()
.This not-so-incidentally also increases code coverage from tests. At
least one of the replaced ternaries was difficult to cover reliably
because operating system/configuration variances were too unpredictable.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes