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

Conversation

Projects
None yet
7 participants
@starkwang
Copy link
Contributor

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
net: port isIPv6 to JS
Porting isIPv6() to JS makes it 2x-5x faster and reduces some
C++ code.
@starkwang

This comment has been minimized.

Copy link
Contributor Author

commented Sep 3, 2018

@mscdex

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor

commented Sep 3, 2018

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

@jasnell

jasnell approved these changes Sep 4, 2018

@mscdex
Copy link
Contributor

left a comment

Making it explicit that additional compatibility is missing yet

@starkwang

This comment has been minimized.

Copy link
Contributor Author

commented Sep 4, 2018

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor

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 Sep 4, 2018

Regex has been updated to be case-insensitive

@BridgeAR

This comment has been minimized.

Copy link
Member

commented Sep 5, 2018

@BridgeAR

This comment has been minimized.

Copy link
Member

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.

@starkwang

This comment has been minimized.

Copy link
Contributor Author

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

This comment has been minimized.

Copy link
Member

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.

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

@starkwang

This comment has been minimized.

Copy link
Contributor Author

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

This comment has been minimized.

Copy link
Contributor

commented Sep 6, 2018

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor Author

commented Sep 11, 2018

@starkwang

This comment has been minimized.

Copy link
Contributor Author

commented Sep 11, 2018

Landed in 8e73594

@starkwang starkwang closed this Sep 11, 2018

starkwang added a commit that referenced this pull request Sep 11, 2018

net: port isIPv6 to JS
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 added a commit that referenced this pull request Sep 11, 2018

net: port isIPv6 to JS
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>

BridgeAR added a commit to BridgeAR/node that referenced this pull request Oct 2, 2018

net: port isIPv6 to JS
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: nodejs#22673
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Roman Reiss <me@silverwind.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.