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

net: port isIPv6() to JS #22673

Closed
wants to merge 2 commits into from
Closed

Conversation

starkwang
Copy link
Contributor

@starkwang starkwang commented Sep 3, 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.

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 nodejs-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
Contributor Author

@mscdex
Copy link
Contributor

mscdex commented Sep 3, 2018

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
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
Copy link
Contributor

@mscdex mscdex left a comment

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
Contributor Author

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
Copy link
Contributor

silverwind commented Sep 4, 2018

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
Copy link
Contributor

mscdex commented Sep 4, 2018

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 review September 4, 2018 21:55

Regex has been updated to be case-insensitive

@BridgeAR
Copy link
Member

BridgeAR commented Sep 5, 2018

@BridgeAR
Copy link
Member

BridgeAR commented Sep 5, 2018

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.

@BridgeAR BridgeAR 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
Copy link
Contributor Author

starkwang commented Sep 5, 2018

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
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
Copy link
Contributor Author

starkwang commented Sep 6, 2018

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:

┌─────────┬───────────────────────────────────────────┬──────────┬──────────┬─────────────┐
│ (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:

┌─────────┬─────────────────────────────────────────────────┬──────────┬──────────┬─────────────┐
│ (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
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
Copy link
Contributor

mscdex commented Sep 6, 2018

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
Member

BridgeAR commented Sep 6, 2018

@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
Copy link
Contributor

mscdex commented Sep 6, 2018

@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):

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):
function hexval(c) {
  if (c - 48 < 10) return c - 48;
  c |= 32;
  if (c - 97 < 6) return c - 97 + 10;
  return -1;
}
function isdigit(c) {
  return c >= 48 && c <= 57;
}
function validate4(src, p) {
  var v;
  var j;
  var ch;
  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) return 0;
  if (p < src.length && src.charCodeAt(p) !== 46/*'.'*/) return 0;
  ++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) return 0;
  if (p < src.length && src.charCodeAt(p) !== 46/*'.'*/) return 0;
  ++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) return 0;
  if (p < src.length && src.charCodeAt(p) !== 46/*'.'*/) return 0;
  ++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) return 0;
  if (p === src.length) return 1;

  return 0;
}
function validate6(src) {
  var p = 0;
  var v;
  var j;
  var ch;
  var brk = -1;
  var d;

  if (src.length === 0) return 0;

  if (src.charCodeAt(p) === 58/*':'*/ && (++p === src.length || src.charCodeAt(p) !== 58/*':'*/)) return 0;

  for (var i = 0; ; ++i) {
    if (src.charCodeAt(p) === 58/*':'*/ && brk < 0) {
      brk = i;
      if (++p === src.length) break;
      if (i === 7) return 0;
      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) return 0;
    if (p === src.length && (brk >= 0 || i === 7)) break;
    if (i === 7) return 0;
    ch = src.charCodeAt(p);
    if (ch !== 58/*':'*/) {
      if (ch !== 46/*'.'*/ || (i < 6 && brk < 0)) return 0;
      if (validate4(src, p - j) <= 0)
        return 0;
      break;
    }
    ++p;
  }

  return 1;
}



// IPv4 Segment
const v4Seg = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
const v4Str = `(${v4Seg}[.]){3}${v4Seg}`;
const IPv4Reg = new RegExp(`^${v4Str}$`);
 // IPv6 Segment
const v6Seg = '(?:[0-9a-fA-F]{1,4})';
const IPv6Reg = new RegExp('^(' +
  `(?:${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,})?$');



const v6 = [
  '::',
  '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'
];

const v6not = [
  '',
  '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');
const n = 1e6;
var results;

function timeIP(ip) {
  var diff_C = process.hrtime();
  for (var i = 0; i < n; ++i)
    isIPv6(ip);
  diff_C = process.hrtime(diff_C);

  var diff_regex = process.hrtime();
  for (var i = 0; i < n; ++i)
    IPv6Reg.test(ip);
  diff_regex = process.hrtime(diff_regex);

  var diff_js = process.hrtime();
  for (var i = 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
Contributor Author

@starkwang
Copy link
Contributor Author

Landed in 8e73594

@starkwang starkwang closed this Sep 11, 2018
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 <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: Roman Reiss <[email protected]>
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 <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: Roman Reiss <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs 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++. cares Issues and PRs related to the c-ares dependency or the cares_wrap binding. net Issues and PRs related to the net subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants