Skip to content

net: port isIPv6() to JS - #22673

Closed
starkwang wants to merge 2 commits into
nodejs:masterfrom
starkwang:net-port-isipv6
Closed

net: port isIPv6() to JS#22673
starkwang wants to merge 2 commits into
nodejs:masterfrom
starkwang:net-port-isipv6

Conversation

@starkwang

@starkwangstarkwang commented Sep 3, 2018

Copy link
Copy Markdown
Contributor

Porting isIPv6() to JS makes it 10%-250% faster in most cases and reduces some C++ code. This change also adds tests for some edge cases.

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

Porting isIPv6() to JS makes it 2x-5x faster and reduces some
C++ code.
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-botnodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. cares Issues and PRs related to the c-ares dependency or the cares_wrap binding. net Issues and PRs related to the net subsystem. labels Sep 3, 2018
@starkwang

Copy link
Copy Markdown
ContributorAuthor

@mscdex

mscdex commented Sep 3, 2018

Copy link
Copy Markdown
Contributor

The matching needs to be case-insensitive to match the existing implementation's behavior.

It might be a good idea to make the set of tests an array and loop through them to check both lower and upper case?

@silverwind

Copy link
Copy Markdown
Contributor

Some more test cases in https://github.com/sindresorhus/ip-regex/blob/master/test.js, I suggest using them all.

mscdex
mscdex previously requested changes Sep 4, 2018

@mscdexmscdex left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Making it explicit that additional compatibility is missing yet

@starkwang

Copy link
Copy Markdown
ContributorAuthor

I've added all the test cases in https://github.com/sindresorhus/ip-regex/blob/master/test.js. It seems no compatibility problems yet.

@silverwind

silverwind commented Sep 4, 2018

Copy link
Copy Markdown
Contributor

The matching needs to be case-insensitive

You mean with i flag and [a-f] character classes? Might be worth testing which one is faster.

@mscdex

mscdex commented Sep 4, 2018

Copy link
Copy Markdown
Contributor

You mean with i flag and [a-f] character classes? Might be worth testing which one is faster.

Before the most recent push/commit, only [a-f] existed in the ipv6 regex, now there is [a-fA-F].

@mscdex
mscdex dismissed their stale reviewSeptember 4, 2018 21:55

Regex has been updated to be case-insensitive

@BridgeAR

Copy link
Copy Markdown
Member

@BridgeAR

Copy link
Copy Markdown
Member

I just ran a small benchmark against all valid test cases and this is the outcome:

new: 234.252ms
old: 275.307ms

The invalid ones loose in the new implementation but comparing all together, they are on par. I guess most passed in IPs will be valid, so it should be a minor performance improvement.

@BridgeARBridgeAR added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Sep 5, 2018
@starkwang

starkwang commented Sep 5, 2018

Copy link
Copy Markdown
ContributorAuthor

You mean with i flag and [a-f] character classes? Might be worth testing which one is faster.

@silverwind I've tried both of them and found no performance difference between them.

@richardlau

Copy link
Copy Markdown
Member

I just ran a small benchmark against all valid test cases and this is the outcome:

new: 234.252ms
old: 275.307ms

The invalid ones loose in the new implementation but comparing all together, they are on par. I guess most passed in IPs will be valid, so it should be a minor performance improvement.

Is the "2x-5x faster" claim still accurate after the case insensitivity change? If not please update the commit message.

@starkwang

starkwang commented Sep 6, 2018

Copy link
Copy Markdown
ContributorAuthor

The "2x-5x faster" claim is not accurate now because I changed the RegExp for some edge cases, which caused performance regression. I will update the commit message.

Here is the benchmark statics for all the valid cases in test-net-isipv6.js:

Details
┌─────────┬───────────────────────────────────────────┬──────────┬──────────┬─────────────┐
│ (index) │ string │ new (ms) │ old (ms) │ improvement │
├─────────┼───────────────────────────────────────────┼──────────┼──────────┼─────────────┤
│ 0 │ '::' │ 1055 │ 1255 │ '18.96%' │
│ 1 │ '1::' │ 1541 │ 1615 │ '4.80%' │
│ 2 │ '::1' │ 1155 │ 1494 │ '29.35%' │
│ 3 │ '1::8' │ 1700 │ 1845 │ '8.53%' │
│ 4 │ '1::7:8' │ 1950 │ 1876 │ '-3.79%' │
│ 5 │ '1:2:3:4:5:6:7:8' │ 1016 │ 2655 │ '161.32%' │
│ 6 │ '1:2:3:4:5:6::8' │ 1726 │ 2488 │ '44.15%' │
│ 7 │ '1:2:3:4:5:6:7::' │ 1016 │ 2761 │ '171.75%' │
│ 8 │ '1:2:3:4:5::7:8' │ 2057 │ 2519 │ '22.46%' │
│ 9 │ '1:2:3:4:5::8' │ 1920 │ 2349 │ '22.34%' │
│ 10 │ '1:2:3::8' │ 2194 │ 2023 │ '-7.79%' │
│ 11 │ '1::4:5:6:7:8' │ 2674 │ 2392 │ '-10.55%' │
│ 12 │ '1::6:7:8' │ 2173 │ 2061 │ '-5.15%' │
│ 13 │ '1::3:4:5:6:7:8' │ 2811 │ 2582 │ '-8.15%' │
│ 14 │ '1:2:3:4::6:7:8' │ 2537 │ 2534 │ '-0.12%' │
│ 15 │ '1:2::4:5:6:7:8' │ 2905 │ 2552 │ '-12.15%' │
│ 16 │ '::2:3:4:5:6:7:8' │ 2332 │ 2574 │ '10.38%' │
│ 17 │ '1:2::8' │ 2105 │ 1870 │ '-11.16%' │
│ 18 │ '2001:0000:1234:0000:0000:C1C0:ABCD:0876' │ 1197 │ 4334 │ '262.07%' │
│ 19 │ '3ffe:0b00:0000:0000:0001:0000:0000:000a' │ 1180 │ 3910 │ '231.36%' │
│ 20 │ 'FF02:0000:0000:0000:0000:0000:0000:0001' │ 1175 │ 4135 │ '251.91%' │
│ 21 │ '0000:0000:0000:0000:0000:0000:0000:0001' │ 1186 │ 3901 │ '228.92%' │
│ 22 │ '0000:0000:0000:0000:0000:0000:0000:0000' │ 1168 │ 3908 │ '234.59%' │
│ 23 │ '::ffff:192.168.1.26' │ 1570 │ 2804 │ '78.60%' │
│ 24 │ '2::10' │ 1782 │ 1766 │ '-0.90%' │
│ 25 │ 'ff02::1' │ 2456 │ 1807 │ '-26.43%' │
│ 26 │ 'fe80::' │ 2173 │ 1739 │ '-19.97%' │
│ 27 │ '2002::' │ 2211 │ 1866 │ '-15.60%' │
│ 28 │ '2001:db8::' │ 2988 │ 2151 │ '-28.01%' │
│ 29 │ '2001:0db8:1234::' │ 3169 │ 2519 │ '-20.51%' │
│ 30 │ '::ffff:0:0' │ 1756 │ 2017 │ '14.86%' │
│ 31 │ '::ffff:192.168.1.1' │ 1436 │ 2717 │ '89.21%' │
│ 32 │ '1:2:3:4::8' │ 2228 │ 2178 │ '-2.24%' │
│ 33 │ '1::2:3:4:5:6:7' │ 2718 │ 2559 │ '-5.85%' │
│ 34 │ '1::2:3:4:5:6' │ 2655 │ 2394 │ '-9.83%' │
│ 35 │ '1::2:3:4:5' │ 2508 │ 2223 │ '-11.36%' │
│ 36 │ '1::2:3:4' │ 2176 │ 2072 │ '-4.78%' │
│ 37 │ '1::2:3' │ 1967 │ 1887 │ '-4.07%' │
│ 38 │ '::2:3:4:5:6:7' │ 2259 │ 2468 │ '9.25%' │
│ 39 │ '::2:3:4:5:6' │ 2086 │ 2225 │ '6.66%' │
│ 40 │ '::2:3:4:5' │ 1955 │ 2036 │ '4.14%' │
│ 41 │ '::2:3:4' │ 1650 │ 1869 │ '13.27%' │
│ 42 │ '::2:3' │ 1435 │ 1685 │ '17.42%' │
│ 43 │ '::8' │ 1155 │ 1486 │ '28.66%' │
│ 44 │ '1:2:3:4:5:6::' │ 1610 │ 2424 │ '50.56%' │
│ 45 │ '1:2:3:4:5::' │ 1882 │ 2260 │ '20.09%' │
│ 46 │ '1:2:3:4::' │ 2107 │ 2095 │ '-0.57%' │
│ 47 │ '1:2:3::' │ 2078 │ 1932 │ '-7.03%' │
│ 48 │ '1:2::' │ 1888 │ 1770 │ '-6.25%' │
│ 49 │ '1:2:3:4::7:8' │ 2464 │ 2358 │ '-4.30%' │
│ 50 │ '1:2:3::7:8' │ 2463 │ 2192 │ '-11.00%' │
│ 51 │ '1:2::7:8' │ 2317 │ 2034 │ '-12.21%' │
│ 52 │ '1:2:3:4:5:6:1.2.3.4' │ 1764 │ 3036 │ '72.11%' │
│ 53 │ '1:2:3:4:5::1.2.3.4' │ 2088 │ 3003 │ '43.82%' │
│ 54 │ '1:2:3:4::1.2.3.4' │ 2270 │ 2769 │ '21.98%' │
│ 55 │ '1:2:3::1.2.3.4' │ 2304 │ 2612 │ '13.37%' │
│ 56 │ '1:2::1.2.3.4' │ 2093 │ 2447 │ '16.91%' │
│ 57 │ '1::1.2.3.4' │ 1739 │ 2288 │ '31.57%' │
│ 58 │ '1:2:3:4::5:1.2.3.4' │ 2321 │ 2970 │ '27.96%' │
│ 59 │ '1:2:3::5:1.2.3.4' │ 2437 │ 2842 │ '16.62%' │
│ 60 │ '1:2::5:1.2.3.4' │ 2193 │ 2625 │ '19.70%' │
│ 61 │ '1::5:1.2.3.4' │ 1819 │ 2479 │ '36.28%' │
│ 62 │ '1::5:11.22.33.44' │ 2028 │ 2734 │ '34.81%' │
│ 63 │ 'fe80::217:f2ff:254.7.237.98' │ 2886 │ 3399 │ '17.78%' │
│ 64 │ 'fe80::217:f2ff:fe07:ed62' │ 3147 │ 2917 │ '-7.31%' │
│ 65 │ '2001:DB8:0:0:8:800:200C:417A' │ 1150 │ 3616 │ '214.43%' │
│ 66 │ 'FF01:0:0:0:0:0:0:101' │ 1071 │ 3023 │ '182.26%' │
│ 67 │ '0:0:0:0:0:0:0:1' │ 1020 │ 2652 │ '160.00%' │
│ 68 │ '0:0:0:0:0:0:0:0' │ 1030 │ 2667 │ '158.93%' │
│ 69 │ '2001:DB8::8:800:200C:417A' │ 4078 │ 3473 │ '-14.84%' │
│ 70 │ 'FF01::101' │ 2579 │ 2008 │ '-22.14%' │
│ 71 │ '0:0:0:0:0:0:13.1.68.3' │ 1791 │ 3124 │ '74.43%' │
│ 72 │ '0:0:0:0:0:FFFF:129.144.52.38' │ 2096 │ 3787 │ '80.68%' │
│ 73 │ '::13.1.68.3' │ 1304 │ 2229 │ '70.94%' │
│ 74 │ '::FFFF:129.144.52.38' │ 1541 │ 3008 │ '95.20%' │
│ 75 │ 'fe80:0000:0000:0000:0204:61ff:fe9d:f156' │ 1190 │ 3866 │ '224.87%' │
│ 76 │ 'fe80:0:0:0:204:61ff:fe9d:f156' │ 1142 │ 3260 │ '185.46%' │
│ 77 │ 'fe80::204:61ff:fe9d:f156' │ 3209 │ 3003 │ '-6.42%' │
│ 78 │ 'fe80:0:0:0:204:61ff:254.157.241.86' │ 2350 │ 3826 │ '62.81%' │
│ 79 │ 'fe80::204:61ff:254.157.241.86' │ 2936 │ 3515 │ '19.72%' │
│ 80 │ 'fe80::1' │ 2348 │ 1810 │ '-22.91%' │
│ 81 │ '2001:0db8:85a3:0000:0000:8a2e:0370:7334' │ 1190 │ 4027 │ '238.40%' │
│ 82 │ '2001:db8:85a3:0:0:8a2e:370:7334' │ 1155 │ 3528 │ '205.45%' │
│ 83 │ '2001:db8:85a3::8a2e:370:7334' │ 3924 │ 3341 │ '-14.86%' │
│ 84 │ '2001:0db8:0000:0000:0000:0000:1428:57ab' │ 1172 │ 4009 │ '242.06%' │
│ 85 │ '2001:0db8:0000:0000:0000::1428:57ab' │ 2963 │ 4455 │ '50.35%' │
│ 86 │ '2001:0db8:0:0:0:0:1428:57ab' │ 1230 │ 3544 │ '188.13%' │
│ 87 │ '2001:0db8:0:0::1428:57ab' │ 3525 │ 3263 │ '-7.43%' │
│ 88 │ '2001:0db8::1428:57ab' │ 3855 │ 2804 │ '-27.26%' │
│ 89 │ '2001:db8::1428:57ab' │ 3589 │ 2703 │ '-24.69%' │
│ 90 │ '::ffff:12.34.56.78' │ 1519 │ 2701 │ '77.81%' │
│ 91 │ '::ffff:0c22:384e' │ 2008 │ 2353 │ '17.18%' │
│ 92 │ '2001:0db8:1234:0000:0000:0000:0000:0000' │ 1175 │ 4039 │ '243.74%' │
│ 93 │ '2001:0db8:1234:ffff:ffff:ffff:ffff:ffff' │ 1209 │ 4041 │ '234.24%' │
│ 94 │ '2001:db8:a::123' │ 3165 │ 2494 │ '-21.20%' │
│ 95 │ '::ffff:192.0.2.128' │ 1651 │ 2747 │ '66.38%' │
│ 96 │ '::ffff:c000:280' │ 1889 │ 2286 │ '21.02%' │
│ 97 │ 'a:b:c:d:e:f:f1:f2' │ 1088 │ 2612 │ '140.07%' │
│ 98 │ 'a:b:c::d:e:f:f1' │ 2702 │ 2550 │ '-5.63%' │
│ 99 │ 'a:b:c::d:e:f' │ 2588 │ 2322 │ '-10.28%' │
│ 100 │ 'a:b:c::d:e' │ 2496 │ 2189 │ '-12.30%' │
│ 101 │ 'a:b:c::d' │ 2215 │ 1987 │ '-10.29%' │
│ 102 │ '::a' │ 1119 │ 1510 │ '34.94%' │
│ 103 │ '::a:b:c' │ 1432 │ 1887 │ '31.77%' │
│ 104 │ '::a:b:c:d:e:f:f1' │ 1886 │ 2625 │ '39.18%' │
│ 105 │ 'a::' │ 1563 │ 1565 │ '0.13%' │
│ 106 │ 'a:b:c::' │ 2143 │ 1893 │ '-11.67%' │
│ 107 │ 'a:b:c:d:e:f:f1::' │ 1071 │ 2596 │ '142.39%' │
│ 108 │ 'a:bb:ccc:dddd:000e:00f:0f::' │ 1178 │ 3218 │ '173.17%' │
│ 109 │ '0:a:0:a:0:0:0:a' │ 1034 │ 2661 │ '157.35%' │
│ 110 │ '0:a:0:0:a:0:0:a' │ 1035 │ 2663 │ '157.29%' │
│ 111 │ '2001:db8:1:1:1:1:0:0' │ 1089 │ 2882 │ '164.65%' │
│ 112 │ '2001:db8:1:1:1:0:0:0' │ 1076 │ 2889 │ '168.49%' │
│ 113 │ '2001:db8:1:1:0:0:0:0' │ 1078 │ 2904 │ '169.39%' │
│ 114 │ '2001:db8:1:0:0:0:0:0' │ 1083 │ 2896 │ '167.41%' │
│ 115 │ '2001:db8:0:0:0:0:0:0' │ 1084 │ 2968 │ '173.80%' │
│ 116 │ '2001:0:0:0:0:0:0:0' │ 1045 │ 2897 │ '177.22%' │
│ 117 │ 'A:BB:CCC:DDDD:000E:00F:0F::' │ 1205 │ 3786 │ '214.19%' │
│ 118 │ '0:0:0:0:0:0:0:a' │ 1022 │ 2673 │ '161.55%' │
│ 119 │ '0:0:0:0:a:0:0:0' │ 1125 │ 2654 │ '135.91%' │
│ 120 │ '0:0:0:a:0:0:0:0' │ 1027 │ 2661 │ '159.10%' │
│ 121 │ 'a:0:0:a:0:0:a:a' │ 1036 │ 2579 │ '148.94%' │
│ 122 │ 'a:0:0:a:0:0:0:a' │ 1030 │ 2569 │ '149.42%' │
│ 123 │ 'a:0:0:0:a:0:0:a' │ 1029 │ 2568 │ '149.56%' │
│ 124 │ 'a:0:0:0:a:0:0:0' │ 1029 │ 2568 │ '149.56%' │
│ 125 │ 'a:0:0:0:0:0:0:0' │ 1021 │ 2567 │ '151.42%' │
│ 126 │ 'fe80::7:8%eth0' │ 2785 │ 2087 │ '-25.06%' │
│ 127 │ 'fe80::7:8%1' │ 2732 │ 2056 │ '-24.74%' │
└─────────┴───────────────────────────────────────────┴──────────┴──────────┴─────────────┘

And here is the benchmark for invalid cases:

Details
┌─────────┬─────────────────────────────────────────────────┬──────────┬──────────┬─────────────┐
│ (index) │ string │ new (ms) │ old (ms) │ improvement │
├─────────┼─────────────────────────────────────────────────┼──────────┼──────────┼─────────────┤
│ 0 │ '' │ 493 │ 1024 │ '107.71%' │
│ 1 │ '1:' │ 943 │ 1335 │ '41.57%' │
│ 2 │ ':1' │ 602 │ 1220 │ '102.66%' │
│ 3 │ '11:36:12' │ 2398 │ 1809 │ '-24.56%' │
│ 4 │ '02001:0000:1234:0000:0000:C1C0:ABCD:0876' │ 1479 │ 1841 │ '24.48%' │
│ 5 │ '2001:0000:1234:0000:00001:C1C0:ABCD:0876' │ 5131 │ 3196 │ '-37.71%' │
│ 6 │ '2001:0000:1234: 0000:0000:C1C0:ABCD:0876' │ 3922 │ 2627 │ '-33.02%' │
│ 7 │ '2001:1:1:1:1:1:255Z255X255Y255' │ 4029 │ 2856 │ '-29.11%' │
│ 8 │ '3ffe:0b00:0000:0001:0000:0000:000a' │ 5900 │ 3496 │ '-40.75%' │
│ 9 │ 'FF02:0000:0000:0000:0000:0000:0000:0000:0001' │ 6284 │ 4212 │ '-32.97%' │
│ 10 │ '3ffe:b00::1::a' │ 3531 │ 2163 │ '-38.74%' │
│ 11 │ '::1111:2222:3333:4444:5555:6666::' │ 6688 │ 3501 │ '-47.65%' │
│ 12 │ '1:2:3::4:5::7:8' │ 3079 │ 2224 │ '-27.77%' │
│ 13 │ '12345::6:7:8' │ 1442 │ 1595 │ '10.61%' │
│ 14 │ '1::5:400.2.3.4' │ 2236 │ 2104 │ '-5.90%' │
│ 15 │ '1::5:260.2.3.4' │ 2267 │ 2107 │ '-7.06%' │
│ 16 │ '1::5:256.2.3.4' │ 2280 │ 2105 │ '-7.68%' │
│ 17 │ '1::5:1.256.3.4' │ 2046 │ 2124 │ '3.81%' │
│ 18 │ '1::5:1.2.256.4' │ 2124 │ 2255 │ '6.17%' │
│ 19 │ '1::5:1.2.3.256' │ 2426 │ 2330 │ '-3.96%' │
│ 20 │ '1::5:300.2.3.4' │ 2314 │ 2120 │ '-8.38%' │
│ 21 │ '1::5:1.300.3.4' │ 2017 │ 2128 │ '5.50%' │
│ 22 │ '1::5:1.2.300.4' │ 2112 │ 2227 │ '5.45%' │
│ 23 │ '1::5:1.2.3.300' │ 2397 │ 2333 │ '-2.67%' │
│ 24 │ '1::5:900.2.3.4' │ 2240 │ 2281 │ '1.83%' │
│ 25 │ '1::5:1.900.3.4' │ 2084 │ 2124 │ '1.92%' │
│ 26 │ '1::5:1.2.900.4' │ 2110 │ 2224 │ '5.40%' │
│ 27 │ '1::5:1.2.3.900' │ 2399 │ 2336 │ '-2.63%' │
│ 28 │ '1::5:300.300.300.300' │ 2240 │ 2173 │ '-2.99%' │
│ 29 │ '1::5:3000.30.30.30' │ 2366 │ 2187 │ '-7.57%' │
│ 30 │ '1::400.2.3.4' │ 1922 │ 1949 │ '1.40%' │
│ 31 │ '1::260.2.3.4' │ 1948 │ 1949 │ '0.05%' │
│ 32 │ '1::256.2.3.4' │ 1948 │ 1945 │ '-0.15%' │
│ 33 │ '1::1.256.3.4' │ 1759 │ 1965 │ '11.71%' │
│ 34 │ '1::1.2.256.4' │ 1904 │ 2082 │ '9.35%' │
│ 35 │ '1::1.2.3.256' │ 2123 │ 2191 │ '3.20%' │
│ 36 │ '1::300.2.3.4' │ 1923 │ 1972 │ '2.55%' │
│ 37 │ '1::1.300.3.4' │ 1732 │ 1972 │ '13.86%' │
│ 38 │ '1::1.2.300.4' │ 1788 │ 2067 │ '15.60%' │
│ 39 │ '1::1.2.3.300' │ 2070 │ 2174 │ '5.02%' │
│ 40 │ '1::900.2.3.4' │ 1932 │ 1959 │ '1.40%' │
│ 41 │ '1::1.900.3.4' │ 1730 │ 1968 │ '13.76%' │
│ 42 │ '1::1.2.900.4' │ 1786 │ 2063 │ '15.51%' │
│ 43 │ '1::1.2.3.900' │ 2066 │ 2216 │ '7.26%' │
│ 44 │ '1::300.300.300.300' │ 1939 │ 2006 │ '3.46%' │
│ 45 │ '1::3000.30.30.30' │ 2040 │ 2036 │ '-0.20%' │
│ 46 │ '::400.2.3.4' │ 1596 │ 1754 │ '9.90%' │
│ 47 │ '::260.2.3.4' │ 1640 │ 1759 │ '7.26%' │
│ 48 │ '::256.2.3.4' │ 1633 │ 1757 │ '7.59%' │
│ 49 │ '::1.256.3.4' │ 1255 │ 1777 │ '41.59%' │
│ 50 │ '::1.2.256.4' │ 1404 │ 1889 │ '34.54%' │
│ 51 │ '::1.2.3.256' │ 1612 │ 1986 │ '23.20%' │
│ 52 │ '::300.2.3.4' │ 1601 │ 1769 │ '10.49%' │
│ 53 │ '::1.300.3.4' │ 1213 │ 1779 │ '46.66%' │
│ 54 │ '::1.2.300.4' │ 1279 │ 1884 │ '47.30%' │
│ 55 │ '::1.2.3.300' │ 1559 │ 1991 │ '27.71%' │
│ 56 │ '::900.2.3.4' │ 1602 │ 1755 │ '9.55%' │
│ 57 │ '::1.900.3.4' │ 1216 │ 1776 │ '46.05%' │
│ 58 │ '::1.2.900.4' │ 1277 │ 1883 │ '47.45%' │
│ 59 │ '::1.2.3.900' │ 1550 │ 1990 │ '28.39%' │
│ 60 │ '::300.300.300.300' │ 1594 │ 1814 │ '13.80%' │
│ 61 │ '::3000.30.30.30' │ 1666 │ 1846 │ '10.80%' │
│ 62 │ '2001:DB8:0:0:8:800:200C:417A:221' │ 5134 │ 3644 │ '-29.02%' │
│ 63 │ 'FF01::101::2' │ 2958 │ 2023 │ '-31.61%' │
│ 64 │ '1111:2222:3333:4444::5555:' │ 6170 │ 3368 │ '-45.41%' │
│ 65 │ '1111:2222:3333::5555:' │ 5133 │ 2676 │ '-47.87%' │
│ 66 │ '1111:2222::5555:' │ 3967 │ 2462 │ '-37.94%' │
│ 67 │ '1111::5555:' │ 3014 │ 2180 │ '-27.67%' │
│ 68 │ '::5555:' │ 1812 │ 1648 │ '-9.05%' │
│ 69 │ ':::' │ 867 │ 1305 │ '50.52%' │
│ 70 │ '1111:' │ 1697 │ 1596 │ '-5.95%' │
│ 71 │ ':' │ 559 │ 1056 │ '88.91%' │
│ 72 │ ':1111:2222:3333:4444::5555' │ 566 │ 1354 │ '139.22%' │
│ 73 │ ':1111:2222:3333::5555' │ 565 │ 1251 │ '121.42%' │
│ 74 │ ':1111:2222::5555' │ 565 │ 1202 │ '112.74%' │
│ 75 │ ':1111::5555' │ 565 │ 1164 │ '106.02%' │
│ 76 │ ':::5555' │ 873 │ 1351 │ '54.75%' │
│ 77 │ '1.2.3.4:1111:2222:3333:4444::5555' │ 821 │ 2431 │ '196.10%' │
│ 78 │ '1.2.3.4:1111:2222:3333::5555' │ 819 │ 2354 │ '187.42%' │
│ 79 │ '1.2.3.4:1111:2222::5555' │ 825 │ 2310 │ '180.00%' │
│ 80 │ '1.2.3.4:1111::5555' │ 819 │ 2204 │ '169.11%' │
│ 81 │ '1.2.3.4::5555' │ 815 │ 2150 │ '163.80%' │
│ 82 │ '1.2.3.4::' │ 816 │ 2221 │ '172.18%' │
│ 83 │ 'fe80:0000:0000:0000:0204:61ff:254.157.241.086' │ 6363 │ 4313 │ '-32.22%' │
│ 84 │ '123' │ 953 │ 1406 │ '47.53%' │
│ 85 │ 'ldkfj' │ 559 │ 1207 │ '115.92%' │
│ 86 │ '2001::FFD3::57ab' │ 2984 │ 2331 │ '-21.88%' │
│ 87 │ '2001:db8:85a3::8a2e:37023:7334' │ 5622 │ 2999 │ '-46.66%' │
│ 88 │ '2001:db8:85a3::8a2e:370k:7334' │ 5492 │ 2991 │ '-45.54%' │
│ 89 │ '1:2:3:4:5:6:7:8:9' │ 3405 │ 2646 │ '-22.29%' │
│ 90 │ '1::2::3' │ 1774 │ 1731 │ '-2.42%' │
│ 91 │ '1:::3:4:5' │ 1437 │ 1605 │ '11.69%' │
│ 92 │ '1:2:3::4:5:6:7:8:9' │ 3359 │ 2646 │ '-21.23%' │
│ 93 │ '::ffff:2.3.4' │ 2158 │ 2174 │ '0.74%' │
│ 94 │ '::ffff:257.1.2.3' │ 2598 │ 2084 │ '-19.78%' │
│ 95 │ '::ffff:12345678901234567890.1.26' │ 2644 │ 2118 │ '-19.89%' │
│ 96 │ '2001:0000:1234:0000:0000:C1C0:ABCD:0876 0' │ 6134 │ 4365 │ '-28.84%' │
│ 97 │ '02001:0000:1234:0000:0000:C1C0:ABCD:0876' │ 1454 │ 1826 │ '25.58%' │
└─────────┴─────────────────────────────────────────────────┴──────────┴──────────┴─────────────┘

Most of valid cases (103/127) have 0% - 250% performance improvement or regression less than
10%. The worst 3th valid cases are

┌─────────┬───────────────────────────────────────────┬──────────┬──────────┬─────────────┐
│ (index) │ string │ new (ms) │ old (ms) │ improvement │
├─────────┼───────────────────────────────────────────┼──────────┼──────────┼─────────────┤
│ 28 │ '2001:db8::' │ 2988 │ 2151 │ '-28.01%' │
│ 88 │ '2001:0db8::1428:57ab' │ 3855 │ 2804 │ '-27.26%' │
│ 25 │ 'ff02::1' │ 2456 │ 1807 │ '-26.43%' │
└─────────┴───────────────────────────────────────────┴──────────┴──────────┴─────────────┘

@silverwind

Copy link
Copy Markdown
Contributor

I'm a bit worried about cases like '2001:0db8::1428:57ab' as this seems to be a very common way to represent an IPv6, but overall, looks to still be an improvement. Maybe @mscdex has more suggestions on how to squeeze out more performance.

@mscdex

mscdex commented Sep 6, 2018

Copy link
Copy Markdown
Contributor

Based on some quick testing, it's easily possible to outperform net.isIPv6() with a non-regex-based solution (in both valid and invalid cases), even with a fairly straight port of inet_pton() from C to JS.

@BridgeAR

Copy link
Copy Markdown
Member

@mscdex it would be nice if you could post your port so the @nodejs/v8 team could have a look at it. Regular expressions should be pretty fast and ideally outperform any hand written version (even tough this regexp is definitely quite complex and that might slow it down).

@mscdex

mscdex commented Sep 6, 2018

Copy link
Copy Markdown
Contributor

@BridgeAR I think it's just the complexity of the regexp that makes it slow and I'm not sure there's really much that can be done to simplify that.

FWIW here are the results from my quick implementation (times are in milliseconds after 1e6 rounds):

Details
Valid IPs
=========
┌─────────────────────────────────────────┬────────┬────────┬────────┐
│ (index) │ C │ regex │ js │
├─────────────────────────────────────────┼────────┼────────┼────────┤
│ :: │ 104.99 │ 122.88 │ 13.59 │
│ 1:: │ 121.30 │ 157.24 │ 31.68 │
│ ::1 │ 106.27 │ 119.63 │ 28.02 │
│ 1::8 │ 124.48 │ 171.09 │ 35.36 │
│ 1::7:8 │ 140.38 │ 191.82 │ 52.82 │
│ 1:2:3:4:5:6:7:8 │ 209.41 │ 113.15 │ 141.58 │
│ 1:2:3:4:5:6::8 │ 201.60 │ 197.85 │ 118.95 │
│ 1:2:3:4:5:6:7:: │ 216.13 │ 114.23 │ 127.10 │
│ 1:2:3:4:5::7:8 │ 208.81 │ 247.02 │ 119.58 │
│ 1:2:3:4:5::8 │ 188.38 │ 236.46 │ 102.55 │
│ 1:2:3::8 │ 157.50 │ 279.56 │ 64.59 │
│ 1::4:5:6:7:8 │ 190.20 │ 274.56 │ 97.38 │
│ 1::6:7:8 │ 156.15 │ 231.53 │ 64.58 │
│ 1::3:4:5:6:7:8 │ 217.35 │ 281.14 │ 119.62 │
│ 1:2:3:4::6:7:8 │ 209.11 │ 307.03 │ 113.79 │
│ 1:2::4:5:6:7:8 │ 210.40 │ 319.13 │ 113.78 │
│ ::2:3:4:5:6:7:8 │ 207.82 │ 254.80 │ 121.21 │
│ 1:2::8 │ 141.52 │ 234.67 │ 48.23 │
│ 2001:0000:1234:0000:0000:C1C0:ABCD:0876 │ 345.88 │ 133.07 │ 197.32 │
│ 3ffe:0b00:0000:0000:0001:0000:0000:000a │ 297.20 │ 131.38 │ 197.07 │
│ FF02:0000:0000:0000:0000:0000:0000:0001 │ 314.07 │ 131.21 │ 197.33 │
│ 0000:0000:0000:0000:0000:0000:0000:0001 │ 297.37 │ 130.54 │ 197.06 │
│ 0000:0000:0000:0000:0000:0000:0000:0000 │ 297.13 │ 130.57 │ 197.09 │
│ ::ffff:192.168.1.26 │ 220.48 │ 163.77 │ 136.72 │
│ 2::10 │ 127.71 │ 184.49 │ 37.16 │
│ ff02::1 │ 130.10 │ 249.92 │ 40.08 │
│ fe80:: │ 124.96 │ 231.29 │ 30.93 │
│ 2002:: │ 136.17 │ 230.92 │ 30.53 │
│ 2001:db8:: │ 158.96 │ 325.86 │ 55.13 │
│ 2001:0db8:1234:: │ 189.24 │ 364.77 │ 77.69 │
│ ::ffff:0:0 │ 148.24 │ 173.17 │ 60.32 │
│ ::ffff:192.168.1.1 │ 209.00 │ 149.32 │ 114.03 │
│ 1:2:3:4::8 │ 166.60 │ 270.77 │ 85.19 │
│ 1::2:3:4:5:6:7 │ 200.38 │ 282.79 │ 125.01 │
│ 1::2:3:4:5:6 │ 185.61 │ 276.49 │ 102.28 │
│ 1::2:3:4:5 │ 170.20 │ 255.58 │ 85.08 │
│ 1::2:3:4 │ 154.09 │ 232.59 │ 67.91 │
│ 1::2:3 │ 139.20 │ 198.87 │ 50.74 │
│ ::2:3:4:5:6:7 │ 183.97 │ 246.43 │ 110.85 │
│ ::2:3:4:5:6 │ 169.02 │ 226.64 │ 87.64 │
│ ::2:3:4:5 │ 153.44 │ 206.18 │ 70.49 │
│ ::2:3:4 │ 137.46 │ 186.18 │ 53.30 │
│ ::2:3 │ 123.99 │ 143.63 │ 36.13 │
│ ::8 │ 105.85 │ 119.40 │ 18.96 │
│ 1:2:3:4:5:6:: │ 191.96 │ 194.81 │ 115.06 │
│ 1:2:3:4:5:: │ 177.55 │ 237.04 │ 98.01 │
│ 1:2:3:4:: │ 163.28 │ 260.28 │ 75.85 │
│ 1:2:3:: │ 148.89 │ 270.01 │ 58.68 │
│ 1:2:: │ 133.70 │ 226.33 │ 41.52 │
│ 1:2:3:4::7:8 │ 182.49 │ 296.36 │ 102.25 │
│ 1:2:3::7:8 │ 168.14 │ 304.92 │ 85.08 │
│ 1:2::7:8 │ 153.86 │ 259.05 │ 68.10 │
│ 1:2:3:4:5:6:1.2.3.4 │ 236.72 │ 205.76 │ 168.39 │
│ 1:2:3:4:5::1.2.3.4 │ 231.83 │ 249.03 │ 157.78 │
│ 1:2:3:4::1.2.3.4 │ 217.58 │ 276.43 │ 132.58 │
│ 1:2:3::1.2.3.4 │ 201.59 │ 285.80 │ 115.37 │
│ 1:2::1.2.3.4 │ 187.46 │ 242.44 │ 98.12 │
│ 1::1.2.3.4 │ 173.61 │ 181.59 │ 81.00 │
│ 1:2:3:4::5:1.2.3.4 │ 233.29 │ 280.06 │ 149.94 │
│ 1:2:3::5:1.2.3.4 │ 219.29 │ 292.66 │ 132.56 │
│ 1:2::5:1.2.3.4 │ 203.51 │ 249.80 │ 115.41 │
│ 1::5:1.2.3.4 │ 188.48 │ 189.06 │ 98.20 │
│ 1::5:11.22.33.44 │ 213.20 │ 203.87 │ 128.82 │
│ fe80::217:f2ff:254.7.237.98 │ 260.47 │ 325.60 │ 163.21 │
│ fe80::217:f2ff:fe07:ed62 │ 219.73 │ 358.52 │ 122.81 │
│ 2001:DB8:0:0:8:800:200C:417A │ 275.51 │ 124.09 │ 171.31 │
│ FF01:0:0:0:0:0:0:101 │ 233.01 │ 128.56 │ 151.63 │
│ 0:0:0:0:0:0:0:1 │ 206.71 │ 113.18 │ 137.11 │
│ 0:0:0:0:0:0:0:0 │ 206.51 │ 112.54 │ 137.10 │
│ 2001:DB8::8:800:200C:417A │ 261.57 │ 444.37 │ 140.59 │
│ FF01::101 │ 147.72 │ 284.17 │ 47.35 │
│ 0:0:0:0:0:0:13.1.68.3 │ 245.44 │ 209.22 │ 183.39 │
│ 0:0:0:0:0:FFFF:129.144.52.38 │ 300.97 │ 244.43 │ 208.77 │
│ ::13.1.68.3 │ 168.33 │ 133.96 │ 81.73 │
│ ::FFFF:129.144.52.38 │ 241.79 │ 164.71 │ 125.83 │
│ fe80:0000:0000:0000:0204:61ff:fe9d:f156 │ 292.77 │ 129.81 │ 194.41 │
│ fe80:0:0:0:204:61ff:fe9d:f156 │ 247.44 │ 120.96 │ 170.86 │
│ fe80::204:61ff:fe9d:f156 │ 219.87 │ 358.44 │ 122.93 │
│ fe80:0:0:0:204:61ff:254.157.241.86 │ 297.61 │ 274.10 │ 217.86 │
│ fe80::204:61ff:254.157.241.86 │ 270.35 │ 326.17 │ 169.52 │
│ fe80::1 │ 130.11 │ 250.16 │ 40.14 │
│ 2001:0db8:85a3:0000:0000:8a2e:0370:7334 │ 303.83 │ 128.38 │ 188.10 │
│ 2001:db8:85a3:0:0:8a2e:370:7334 │ 265.56 │ 133.41 │ 177.80 │
│ 2001:db8:85a3::8a2e:370:7334 │ 250.85 │ 454.60 │ 146.98 │
│ 2001:0db8:0000:0000:0000:0000:1428:57ab │ 303.57 │ 134.85 │ 194.02 │
│ 2001:0db8:0000:0000:0000::1428:57ab │ 292.05 │ 315.75 │ 168.12 │
│ 2001:0db8:0:0:0:0:1428:57ab │ 250.56 │ 119.46 │ 168.91 │
│ 2001:0db8:0:0::1428:57ab │ 234.68 │ 371.57 │ 132.49 │
│ 2001:0db8::1428:57ab │ 206.32 │ 426.23 │ 98.19 │
│ 2001:db8::1428:57ab │ 202.60 │ 381.51 │ 99.05 │
│ ::ffff:12.34.56.78 │ 205.66 │ 158.49 │ 116.78 │
│ ::ffff:0c22:384e │ 171.93 │ 200.39 │ 77.81 │
│ 2001:0db8:1234:0000:0000:0000:0000:0000 │ 303.56 │ 140.10 │ 193.02 │
│ 2001:0db8:1234:ffff:ffff:ffff:ffff:ffff │ 303.62 │ 127.86 │ 197.31 │
│ 2001:db8:a::123 │ 184.83 │ 315.79 │ 88.89 │
│ ::ffff:192.0.2.128 │ 209.78 │ 189.07 │ 115.82 │
│ ::ffff:c000:280 │ 167.47 │ 207.16 │ 73.64 │
│ a:b:c:d:e:f:f1:f2 │ 203.33 │ 114.21 │ 145.05 │
│ a:b:c::d:e:f:f1 │ 199.14 │ 319.08 │ 123.01 │
│ a:b:c::d:e:f │ 179.63 │ 313.40 │ 102.26 │
│ a:b:c::d:e │ 164.18 │ 286.54 │ 85.15 │
│ a:b:c::d │ 147.70 │ 270.88 │ 67.92 │
│ ::a │ 105.78 │ 118.93 │ 18.96 │
│ ::a:b:c │ 137.52 │ 166.53 │ 53.31 │
│ ::a:b:c:d:e:f:f1 │ 204.09 │ 215.27 │ 130.44 │
│ a:: │ 114.58 │ 159.12 │ 24.35 │
│ a:b:c:: │ 144.43 │ 266.94 │ 58.68 │
│ a:b:c:d:e:f:f1:: │ 205.68 │ 120.59 │ 135.83 │
│ a:bb:ccc:dddd:000e:00f:0f:: │ 245.34 │ 125.94 │ 163.73 │
│ 0:a:0:a:0:0:0:a │ 207.25 │ 111.74 │ 133.19 │
│ 0:a:0:0:a:0:0:a │ 205.60 │ 112.17 │ 138.50 │
│ 2001:db8:1:1:1:1:0:0 │ 225.03 │ 115.30 │ 150.84 │
│ 2001:db8:1:1:1:0:0:0 │ 225.14 │ 127.22 │ 150.87 │
│ 2001:db8:1:1:0:0:0:0 │ 225.01 │ 116.02 │ 150.81 │
│ 2001:db8:1:0:0:0:0:0 │ 225.07 │ 121.30 │ 150.88 │
│ 2001:db8:0:0:0:0:0:0 │ 225.09 │ 115.31 │ 150.82 │
│ 2001:0:0:0:0:0:0:0 │ 225.15 │ 114.55 │ 143.25 │
│ A:BB:CCC:DDDD:000E:00F:0F:: │ 316.86 │ 131.73 │ 163.70 │
│ 0:0:0:0:0:0:0:a │ 206.68 │ 115.84 │ 138.07 │
│ 0:0:0:0:a:0:0:0 │ 206.89 │ 113.80 │ 133.23 │
│ 0:0:0:a:0:0:0:0 │ 206.20 │ 114.81 │ 133.19 │
│ a:0:0:a:0:0:a:a │ 201.88 │ 112.33 │ 138.58 │
│ a:0:0:a:0:0:0:a │ 202.93 │ 112.28 │ 133.28 │
│ a:0:0:0:a:0:0:a │ 200.94 │ 111.77 │ 133.37 │
│ a:0:0:0:a:0:0:0 │ 204.12 │ 114.59 │ 133.45 │
│ a:0:0:0:0:0:0:0 │ 204.69 │ 116.73 │ 137.32 │
│ fe80::7:8%eth0 │ 150.91 │ 315.41 │ 61.33 │
│ fe80::7:8%1 │ 149.27 │ 312.47 │ 61.43 │
└─────────────────────────────────────────┴────────┴────────┴────────┘
Invalid IPs
===========
┌───────────────────────────────────────────────┬────────┬────────┬────────┐
│ (index) │ C │ regex │ js │
├───────────────────────────────────────────────┼────────┼────────┼────────┤
│ 123 │ 107.27 │ 100.95 │ 31.27 │
│ │ 81.79 │ 56.41 │ 1.54 │
│ 1: │ 103.37 │ 98.31 │ 44.36 │
│ :1 │ 86.00 │ 68.70 │ 6.92 │
│ 11:36:12 │ 145.49 │ 308.47 │ 93.72 │
│ 02001:0000:1234:0000:0000:C1C0:ABCD:0876 │ 129.19 │ 173.17 │ 34.31 │
│ 2001:0000:1234:0000:00001:C1C0:ABCD:0876 │ 234.46 │ 566.64 │ 161.34 │
│ 2001:0000:1234: 0000:0000:C1C0:ABCD:0876 │ 202.93 │ 487.47 │ 107.36 │
│ 2001:1:1:1:1:1:255Z255X255Y255 │ 234.33 │ 490.28 │ 186.33 │
│ 3ffe:0b00:0000:0001:0000:0000:000a │ 270.34 │ 641.02 │ 219.12 │
│ FF02:0000:0000:0000:0000:0000:0000:0000:0001 │ 327.70 │ 663.40 │ 242.17 │
│ 3ffe:b00::1::a │ 177.28 │ 405.48 │ 112.95 │
│ ::1111:2222:3333:4444:5555:6666:: │ 268.61 │ 696.48 │ 216.10 │
│ 1:2:3::4:5::7:8 │ 185.83 │ 373.05 │ 144.11 │
│ 12345::6:7:8 │ 121.54 │ 173.22 │ 34.34 │
│ 1::5:400.2.3.4 │ 172.13 │ 254.93 │ 110.40 │
│ 1::5:260.2.3.4 │ 170.53 │ 244.84 │ 110.32 │
│ 1::5:256.2.3.4 │ 172.37 │ 245.16 │ 111.51 │
│ 1::5:1.256.3.4 │ 175.60 │ 225.32 │ 109.78 │
│ 1::5:1.2.256.4 │ 180.70 │ 247.88 │ 126.19 │
│ 1::5:1.2.3.256 │ 191.20 │ 283.91 │ 140.14 │
│ 1::5:300.2.3.4 │ 170.09 │ 254.72 │ 110.68 │
│ 1::5:1.300.3.4 │ 173.48 │ 224.03 │ 108.95 │
│ 1::5:1.2.300.4 │ 180.61 │ 244.66 │ 126.24 │
│ 1::5:1.2.3.300 │ 190.32 │ 281.23 │ 140.46 │
│ 1::5:900.2.3.4 │ 175.02 │ 253.75 │ 111.08 │
│ 1::5:1.900.3.4 │ 173.30 │ 223.19 │ 108.82 │
│ 1::5:1.2.900.4 │ 181.95 │ 245.83 │ 126.27 │
│ 1::5:1.2.3.900 │ 190.46 │ 281.19 │ 140.31 │
│ 1::5:300.300.300.300 │ 176.92 │ 253.94 │ 110.50 │
│ 1::5:3000.30.30.30 │ 178.17 │ 269.77 │ 109.80 │
│ 1::400.2.3.4 │ 157.34 │ 212.07 │ 86.74 │
│ 1::260.2.3.4 │ 156.04 │ 213.57 │ 86.98 │
│ 1::256.2.3.4 │ 158.18 │ 214.06 │ 87.10 │
│ 1::1.256.3.4 │ 160.41 │ 183.66 │ 85.66 │
│ 1::1.2.256.4 │ 167.70 │ 205.65 │ 102.65 │
│ 1::1.2.3.256 │ 178.39 │ 242.69 │ 114.22 │
│ 1::300.2.3.4 │ 161.56 │ 212.28 │ 87.57 │
│ 1::1.300.3.4 │ 160.95 │ 181.44 │ 85.48 │
│ 1::1.2.300.4 │ 166.15 │ 204.39 │ 102.67 │
│ 1::1.2.3.300 │ 179.66 │ 240.90 │ 114.21 │
│ 1::900.2.3.4 │ 159.57 │ 212.12 │ 86.96 │
│ 1::1.900.3.4 │ 160.21 │ 181.42 │ 85.49 │
│ 1::1.2.900.4 │ 169.03 │ 204.44 │ 102.65 │
│ 1::1.2.3.900 │ 174.93 │ 241.35 │ 114.26 │
│ 1::300.300.300.300 │ 163.26 │ 212.21 │ 87.52 │
│ 1::3000.30.30.30 │ 164.91 │ 228.57 │ 85.73 │
│ ::400.2.3.4 │ 140.56 │ 177.84 │ 65.34 │
│ ::260.2.3.4 │ 139.61 │ 180.97 │ 65.37 │
│ ::256.2.3.4 │ 138.00 │ 181.11 │ 64.84 │
│ ::1.256.3.4 │ 141.30 │ 141.94 │ 64.15 │
│ ::1.2.256.4 │ 150.02 │ 161.87 │ 80.71 │
│ ::1.2.3.256 │ 154.56 │ 199.63 │ 89.90 │
│ ::300.2.3.4 │ 139.73 │ 177.67 │ 64.92 │
│ ::1.300.3.4 │ 140.13 │ 139.81 │ 64.07 │
│ ::1.2.300.4 │ 148.12 │ 159.46 │ 80.82 │
│ ::1.2.3.300 │ 157.94 │ 196.38 │ 90.14 │
│ ::900.2.3.4 │ 138.14 │ 177.79 │ 64.70 │
│ ::1.900.3.4 │ 139.94 │ 140.00 │ 64.09 │
│ ::1.2.900.4 │ 147.25 │ 159.50 │ 80.90 │
│ ::1.2.3.900 │ 153.76 │ 196.45 │ 89.83 │
│ ::300.300.300.300 │ 144.33 │ 178.03 │ 65.24 │
│ ::3000.30.30.30 │ 143.73 │ 194.24 │ 63.86 │
│ 2001:DB8:0:0:8:800:200C:417A:221 │ 311.96 │ 563.52 │ 228.97 │
│ FF01::101::2 │ 168.69 │ 340.05 │ 88.21 │
│ 1111:2222:3333:4444::5555: │ 243.78 │ 668.97 │ 181.70 │
│ 1111:2222:3333::5555: │ 217.78 │ 599.97 │ 141.46 │
│ 1111:2222::5555: │ 190.33 │ 501.53 │ 111.30 │
│ 1111::5555: │ 164.45 │ 342.44 │ 82.17 │
│ ::5555: │ 124.35 │ 199.43 │ 54.38 │
│ ::: │ 109.17 │ 96.14 │ 28.28 │
│ 1111: │ 120.43 │ 174.08 │ 43.78 │
│ : │ 85.49 │ 67.59 │ 3.08 │
│ :1111:2222:3333:4444::5555 │ 98.09 │ 68.60 │ 6.92 │
│ :1111:2222:3333::5555 │ 95.99 │ 68.12 │ 6.92 │
│ :1111:2222::5555 │ 93.57 │ 67.79 │ 6.92 │
│ :1111::5555 │ 91.56 │ 68.20 │ 6.92 │
│ :::5555 │ 112.35 │ 98.14 │ 28.04 │
│ 1.2.3.4:1111:2222:3333:4444::5555 │ 183.07 │ 91.70 │ 27.16 │
│ 1.2.3.4:1111:2222:3333::5555 │ 183.36 │ 91.61 │ 27.16 │
│ 1.2.3.4:1111:2222::5555 │ 183.27 │ 92.03 │ 27.16 │
│ 1.2.3.4:1111::5555 │ 173.17 │ 91.85 │ 27.17 │
│ 1.2.3.4::5555 │ 170.07 │ 92.14 │ 27.16 │
│ 1.2.3.4:: │ 163.74 │ 91.98 │ 27.16 │
│ fe80:0000:0000:0000:0204:61ff:254.157.241.086 │ 336.63 │ 674.15 │ 298.03 │
│ ldkfj │ 98.44 │ 68.05 │ 17.42 │
│ 2001::FFD3::57ab │ 192.44 │ 348.30 │ 86.92 │
│ 2001:db8:85a3::8a2e:37023:7334 │ 237.04 │ 672.99 │ 165.11 │
│ 2001:db8:85a3::8a2e:370k:7334 │ 244.03 │ 656.18 │ 166.42 │
│ 1:2:3:4:5:6:7:8:9 │ 218.16 │ 377.23 │ 191.17 │
│ 1::2::3 │ 142.96 │ 198.58 │ 73.18 │
│ 1:::3:4:5 │ 131.28 │ 146.52 │ 49.65 │
│ 1:2:3::4:5:6:7:8:9 │ 230.79 │ 399.85 │ 181.36 │
│ ::ffff:2.3.4 │ 167.77 │ 258.94 │ 107.14 │
│ ::ffff:257.1.2.3 │ 165.81 │ 281.25 │ 96.90 │
│ ::ffff:12345678901234567890.1.26 │ 161.34 │ 299.28 │ 75.87 │
│ 2001:0000:1234:0000:0000:C1C0:ABCD:0876 0 │ 344.39 │ 666.44 │ 245.23 │
└───────────────────────────────────────────────┴────────┴────────┴────────┘

Yes, there are some cases where the regex beats the simple js implementation and it's possible the js code could be improved more, but it still beats calling out to C in every input tested.

Here is the code I used to produce the results (using node v10.9.0):
Details
functionhexval(c){if(c-48<10)returnc-48;c|=32;if(c-97<6)returnc-97+10;return-1;}functionisdigit(c){returnc>=48&&c<=57;}functionvalidate4(src,p){varv;varj;varch;for(v=0,j=0;j<3&&p<src.length&&isdigit(ch=src.charCodeAt(p));++j,++p)v=10*v+ch-48;if(j===0||(j>1&&src.charCodeAt(p-j)===48/*'0'*/)||v>255)return0;if(p<src.length&&src.charCodeAt(p)!==46/*'.'*/)return0;++p;for(v=0,j=0;j<3&&p<src.length&&isdigit(ch=src.charCodeAt(p));++j,++p)v=10*v+ch-48;if(j===0||(j>1&&src.charCodeAt(p-j)===48/*'0'*/)||v>255)return0;if(p<src.length&&src.charCodeAt(p)!==46/*'.'*/)return0;++p;for(v=0,j=0;j<3&&p<src.length&&isdigit(ch=src.charCodeAt(p));++j,++p)v=10*v+ch-48;if(j===0||(j>1&&src.charCodeAt(p-j)===48/*'0'*/)||v>255)return0;if(p<src.length&&src.charCodeAt(p)!==46/*'.'*/)return0;++p;for(v=0,j=0;j<3&&p<src.length&&isdigit(ch=src.charCodeAt(p));++j,++p)v=10*v+ch-48;if(j===0||(j>1&&src.charCodeAt(p-j)===48/*'0'*/)||v>255)return0;if(p===src.length)return1;return0;}functionvalidate6(src){varp=0;varv;varj;varch;varbrk=-1;vard;if(src.length===0)return0;if(src.charCodeAt(p)===58/*':'*/&&(++p===src.length||src.charCodeAt(p)!==58/*':'*/))return0;for(vari=0;;++i){if(src.charCodeAt(p)===58/*':'*/&&brk<0){brk=i;if(++p===src.length)break;if(i===7)return0;continue;}for(v=0,j=0;j<4&&p<src.length&&(d=hexval(src.charCodeAt(p)))>=0;++j,++p)v=16*v+d;if(j<4&&p<src.length&&src.charCodeAt(p)===37/*'%'*/)break;if(j===0)return0;if(p===src.length&&(brk>=0||i===7))break;if(i===7)return0;ch=src.charCodeAt(p);if(ch!==58/*':'*/){if(ch!==46/*'.'*/||(i<6&&brk<0))return0;if(validate4(src,p-j)<=0)return0;break;}++p;}return1;}// IPv4 Segmentconstv4Seg='(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';constv4Str=`(${v4Seg}[.]){3}${v4Seg}`;constIPv4Reg=newRegExp(`^${v4Str}$`);// IPv6 Segmentconstv6Seg='(?:[0-9a-fA-F]{1,4})';constIPv6Reg=newRegExp('^('+`(?:${v6Seg}:){7}(?:${v6Seg}|:)|`+`(?:${v6Seg}:){6}(?:${v4Str}|:${v6Seg}|:)|`+`(?:${v6Seg}:){5}(?::${v4Str}|(:${v6Seg}){1,2}|:)|`+`(?:${v6Seg}:){4}(?:(:${v6Seg}){0,1}:${v4Str}|(:${v6Seg}){1,3}|:)|`+`(?:${v6Seg}:){3}(?:(:${v6Seg}){0,2}:${v4Str}|(:${v6Seg}){1,4}|:)|`+`(?:${v6Seg}:){2}(?:(:${v6Seg}){0,3}:${v4Str}|(:${v6Seg}){1,5}|:)|`+`(?:${v6Seg}:){1}(?:(:${v6Seg}){0,4}:${v4Str}|(:${v6Seg}){1,6}|:)|`+`(?::((?::${v6Seg}){0,5}:${v4Str}|(?::${v6Seg}){1,7}|:))`+')(%[0-9a-zA-Z]{1,})?$');constv6=['::','1::','::1','1::8','1::7:8','1:2:3:4:5:6:7:8','1:2:3:4:5:6::8','1:2:3:4:5:6:7::','1:2:3:4:5::7:8','1:2:3:4:5::8','1:2:3::8','1::4:5:6:7:8','1::6:7:8','1::3:4:5:6:7:8','1:2:3:4::6:7:8','1:2::4:5:6:7:8','::2:3:4:5:6:7:8','1:2::8','2001:0000:1234:0000:0000:C1C0:ABCD:0876','3ffe:0b00:0000:0000:0001:0000:0000:000a','FF02:0000:0000:0000:0000:0000:0000:0001','0000:0000:0000:0000:0000:0000:0000:0001','0000:0000:0000:0000:0000:0000:0000:0000','::ffff:192.168.1.26','2::10','ff02::1','fe80::','2002::','2001:db8::','2001:0db8:1234::','::ffff:0:0','::ffff:192.168.1.1','1:2:3:4::8','1::2:3:4:5:6:7','1::2:3:4:5:6','1::2:3:4:5','1::2:3:4','1::2:3','::2:3:4:5:6:7','::2:3:4:5:6','::2:3:4:5','::2:3:4','::2:3','::8','1:2:3:4:5:6::','1:2:3:4:5::','1:2:3:4::','1:2:3::','1:2::','1:2:3:4::7:8','1:2:3::7:8','1:2::7:8','1:2:3:4:5:6:1.2.3.4','1:2:3:4:5::1.2.3.4','1:2:3:4::1.2.3.4','1:2:3::1.2.3.4','1:2::1.2.3.4','1::1.2.3.4','1:2:3:4::5:1.2.3.4','1:2:3::5:1.2.3.4','1:2::5:1.2.3.4','1::5:1.2.3.4','1::5:11.22.33.44','fe80::217:f2ff:254.7.237.98','fe80::217:f2ff:fe07:ed62','2001:DB8:0:0:8:800:200C:417A','FF01:0:0:0:0:0:0:101','0:0:0:0:0:0:0:1','0:0:0:0:0:0:0:0','2001:DB8::8:800:200C:417A','FF01::101','0:0:0:0:0:0:13.1.68.3','0:0:0:0:0:FFFF:129.144.52.38','::13.1.68.3','::FFFF:129.144.52.38','fe80:0000:0000:0000:0204:61ff:fe9d:f156','fe80:0:0:0:204:61ff:fe9d:f156','fe80::204:61ff:fe9d:f156','fe80:0:0:0:204:61ff:254.157.241.86','fe80::204:61ff:254.157.241.86','fe80::1','2001:0db8:85a3:0000:0000:8a2e:0370:7334','2001:db8:85a3:0:0:8a2e:370:7334','2001:db8:85a3::8a2e:370:7334','2001:0db8:0000:0000:0000:0000:1428:57ab','2001:0db8:0000:0000:0000::1428:57ab','2001:0db8:0:0:0:0:1428:57ab','2001:0db8:0:0::1428:57ab','2001:0db8::1428:57ab','2001:db8::1428:57ab','::ffff:12.34.56.78','::ffff:0c22:384e','2001:0db8:1234:0000:0000:0000:0000:0000','2001:0db8:1234:ffff:ffff:ffff:ffff:ffff','2001:db8:a::123','::ffff:192.0.2.128','::ffff:c000:280','a:b:c:d:e:f:f1:f2','a:b:c::d:e:f:f1','a:b:c::d:e:f','a:b:c::d:e','a:b:c::d','::a','::a:b:c','::a:b:c:d:e:f:f1','a::','a:b:c::','a:b:c:d:e:f:f1::','a:bb:ccc:dddd:000e:00f:0f::','0:a:0:a:0:0:0:a','0:a:0:0:a:0:0:a','2001:db8:1:1:1:1:0:0','2001:db8:1:1:1:0:0:0','2001:db8:1:1:0:0:0:0','2001:db8:1:0:0:0:0:0','2001:db8:0:0:0:0:0:0','2001:0:0:0:0:0:0:0','A:BB:CCC:DDDD:000E:00F:0F::','0:0:0:0:0:0:0:a','0:0:0:0:a:0:0:0','0:0:0:a:0:0:0:0','a:0:0:a:0:0:a:a','a:0:0:a:0:0:0:a','a:0:0:0:a:0:0:a','a:0:0:0:a:0:0:0','a:0:0:0:0:0:0:0','fe80::7:8%eth0','fe80::7:8%1'];constv6not=['','1:',':1','11:36:12','02001:0000:1234:0000:0000:C1C0:ABCD:0876','2001:0000:1234:0000:00001:C1C0:ABCD:0876','2001:0000:1234: 0000:0000:C1C0:ABCD:0876','2001:1:1:1:1:1:255Z255X255Y255','3ffe:0b00:0000:0001:0000:0000:000a','FF02:0000:0000:0000:0000:0000:0000:0000:0001','3ffe:b00::1::a','::1111:2222:3333:4444:5555:6666::','1:2:3::4:5::7:8','12345::6:7:8','1::5:400.2.3.4','1::5:260.2.3.4','1::5:256.2.3.4','1::5:1.256.3.4','1::5:1.2.256.4','1::5:1.2.3.256','1::5:300.2.3.4','1::5:1.300.3.4','1::5:1.2.300.4','1::5:1.2.3.300','1::5:900.2.3.4','1::5:1.900.3.4','1::5:1.2.900.4','1::5:1.2.3.900','1::5:300.300.300.300','1::5:3000.30.30.30','1::400.2.3.4','1::260.2.3.4','1::256.2.3.4','1::1.256.3.4','1::1.2.256.4','1::1.2.3.256','1::300.2.3.4','1::1.300.3.4','1::1.2.300.4','1::1.2.3.300','1::900.2.3.4','1::1.900.3.4','1::1.2.900.4','1::1.2.3.900','1::300.300.300.300','1::3000.30.30.30','::400.2.3.4','::260.2.3.4','::256.2.3.4','::1.256.3.4','::1.2.256.4','::1.2.3.256','::300.2.3.4','::1.300.3.4','::1.2.300.4','::1.2.3.300','::900.2.3.4','::1.900.3.4','::1.2.900.4','::1.2.3.900','::300.300.300.300','::3000.30.30.30','2001:DB8:0:0:8:800:200C:417A:221','FF01::101::2','1111:2222:3333:4444::5555:','1111:2222:3333::5555:','1111:2222::5555:','1111::5555:','::5555:',':::','1111:',':',':1111:2222:3333:4444::5555',':1111:2222:3333::5555',':1111:2222::5555',':1111::5555',':::5555','1.2.3.4:1111:2222:3333:4444::5555','1.2.3.4:1111:2222:3333::5555','1.2.3.4:1111:2222::5555','1.2.3.4:1111::5555','1.2.3.4::5555','1.2.3.4::','fe80:0000:0000:0000:0204:61ff:254.157.241.086','123','ldkfj','2001::FFD3::57ab','2001:db8:85a3::8a2e:37023:7334','2001:db8:85a3::8a2e:370k:7334','1:2:3:4:5:6:7:8:9','1::2::3','1:::3:4:5','1:2:3::4:5:6:7:8:9','::ffff:2.3.4','::ffff:257.1.2.3','::ffff:12345678901234567890.1.26','2001:0000:1234:0000:0000:C1C0:ABCD:0876 0','02001:0000:1234:0000:0000:C1C0:ABCD:0876'];const{ isIPv6 }=require('net');constn=1e6;varresults;functiontimeIP(ip){vardiff_C=process.hrtime();for(vari=0;i<n;++i)isIPv6(ip);diff_C=process.hrtime(diff_C);vardiff_regex=process.hrtime();for(vari=0;i<n;++i)IPv6Reg.test(ip);diff_regex=process.hrtime(diff_regex);vardiff_js=process.hrtime();for(vari=0;i<n;++i)validate6(ip);diff_js=process.hrtime(diff_js);results[ip]={C: (diff_C[0]*1000+diff_C[1]/1e6).toFixed(2),regex: (diff_regex[0]*1000+diff_regex[1]/1e6).toFixed(2),js: (diff_js[0]*1000+diff_js[1]/1e6).toFixed(2),};}console.log('Valid IPs');console.log('=========');results=Object.create(null);v6.forEach(timeIP);console.table(results);console.log('Invalid IPs');console.log('===========');results=Object.create(null);v6not.forEach(timeIP);console.table(results);

@starkwang

Copy link
Copy Markdown
ContributorAuthor

@starkwang

Copy link
Copy Markdown
ContributorAuthor

Landed in 8e73594

starkwang added a commit that referenced this pull request Sep 11, 2018
Porting isIPv6() to JS makes it 10%-250% faster in most cases and
reduces some C++ code. This change also adds tests for some edge
cases.
PR-URL: #22673
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Roman Reiss <me@silverwind.io>
targos pushed a commit that referenced this pull request Sep 11, 2018
Porting isIPv6() to JS makes it 10%-250% faster in most cases and
reduces some C++ code. This change also adds tests for some edge
cases.
PR-URL: #22673
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Roman Reiss <me@silverwind.io>
@targostargos mentioned this pull request Sep 18, 2018
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author readyPRs that have at least one approval, no pending requests for changes, and a CI started.c++Issues and PRs that require attention from people who are familiar with C++.caresIssues and PRs related to the c-ares dependency or the cares_wrap binding.netIssues and PRs related to the net subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@starkwang@nodejs-github-bot@mscdex@silverwind@BridgeAR@richardlau@jasnell