Skip to content
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: improve performance #13261

Merged
merged 3 commits into from
Jun 2, 2017
Merged

Conversation

mscdex
Copy link
Contributor

@mscdex mscdex commented May 28, 2017

Example results with the included benchmark file:

                                                       improvement confidence      p.value
 dns/lookup.js n=5000000 all="false" name="127.0.0.1"     83.78 %        *** 1.619328e-41

I looked at the original commit where the "forced" async callback mechanism was added and I was not able to reproduce the sync callback issue with the tests included with that commit. My guess is that either c-ares changed or we have since manually taken care of such possible sync situations (e.g. empty hostnames or looking up an IP address).

I've also ran the dns tests in test/internet and there are no problems there either.

CI: https://ci.nodejs.org/job/node-test-pull-request/8343/

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)
  • dns

@mscdex mscdex added dns Issues and PRs related to the dns subsystem. performance Issues and PRs related to the performance of Node.js. labels May 28, 2017
@nodejs-github-bot nodejs-github-bot added the dns Issues and PRs related to the dns subsystem. label May 28, 2017
@mscdex mscdex force-pushed the dns-remove-callback-overhead branch from b34df4d to 33759f2 Compare May 28, 2017 02:05
const lookup = require('dns').lookup;

const bench = common.createBenchmark(main, {
name: ['', '127.0.0.1', '::1'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to throw in localhost so that there's a hostname lookup since that probably takes a different path through the code?

Copy link
Contributor Author

@mscdex mscdex May 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose this list because they don't actually hit libuv and so (in this particular case) it is a better measure of the forced async callback change. Also when you start passing in non-empty hostnames, the n value will need to be lowered quite a bit.

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 96-111
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 112-127
];
function isIPv4(str) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason to not use net.isIPv4 here?

Copy link
Contributor Author

@mscdex mscdex May 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Faster to not have to call into C++ land IIRC, especially since we only need to check at most a few characters anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mscdex how much faster is this compared to something simpler like

function digits(code) {
  return code >= 48 && code <= 57;
}

Copy link
Contributor Author

@mscdex mscdex May 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lpinca ~19% faster.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

@mscdex
Copy link
Contributor Author

mscdex commented Jun 1, 2017

/cc @nodejs/collaborators

0.0.0.0 is more common than other special ipv4 addresses, so
it is possible that we may not get ENOTFOUND for such addresses.
Instead, this commit uses a less common address that is reserved
for documentation (RFC) use only.

PR-URL: nodejs#13261
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: James M Snell <jasnell@gmail.com>
It appears that either c-ares no longer calls callbacks synchronously
or we have since explicitly taken care of the scenarios in which
c-ares would call callbacks synchronously (e.g. resolving an IP
address or an empty hostname). Therefore we no longer need to have
machinery in place to handle possible synchronous callback invocation.
This improves performance significantly.

PR-URL: nodejs#13261
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: nodejs#13261
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: James M Snell <jasnell@gmail.com>
@mscdex mscdex force-pushed the dns-remove-callback-overhead branch from 33759f2 to 3c989de Compare June 2, 2017 02:01
@mscdex mscdex merged commit 3c989de into nodejs:master Jun 2, 2017
@mscdex mscdex deleted the dns-remove-callback-overhead branch June 2, 2017 02:13
jasnell pushed a commit that referenced this pull request Jun 5, 2017
0.0.0.0 is more common than other special ipv4 addresses, so
it is possible that we may not get ENOTFOUND for such addresses.
Instead, this commit uses a less common address that is reserved
for documentation (RFC) use only.

PR-URL: #13261
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: James M Snell <jasnell@gmail.com>
jasnell pushed a commit that referenced this pull request Jun 5, 2017
It appears that either c-ares no longer calls callbacks synchronously
or we have since explicitly taken care of the scenarios in which
c-ares would call callbacks synchronously (e.g. resolving an IP
address or an empty hostname). Therefore we no longer need to have
machinery in place to handle possible synchronous callback invocation.
This improves performance significantly.

PR-URL: #13261
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: James M Snell <jasnell@gmail.com>
jasnell pushed a commit that referenced this pull request Jun 5, 2017
PR-URL: #13261
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: James M Snell <jasnell@gmail.com>
@jasnell jasnell mentioned this pull request Jun 5, 2017
@gibfahn gibfahn mentioned this pull request Jun 15, 2017
3 tasks
@MylesBorins MylesBorins added baking-for-lts PRs that need to wait before landing in a LTS release. lts-watch-v6.x labels Jul 17, 2017
@MylesBorins
Copy link
Contributor

should this land in LTS? If so it will need to bake a bit longer.

Please change labels as appropriate

@MylesBorins MylesBorins removed the baking-for-lts PRs that need to wait before landing in a LTS release. label Aug 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dns Issues and PRs related to the dns subsystem. performance Issues and PRs related to the performance of Node.js.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants