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

http: various performance improvements #10558

Merged
merged 9 commits into from
Jan 11, 2017
Merged

http: various performance improvements #10558

merged 9 commits into from
Jan 11, 2017

Conversation

mscdex
Copy link
Contributor

@mscdex mscdex commented Dec 31, 2016

These commits bring 3-11% performance increase (this is on top of the performance improvements made recently in #10445, #10443, and #6533). The performance increases are greater when you start setting/adding more headers than the http benchmarks currently use (just 2 currently).

When using the 'simple' http benchmark, I had to reduce the http client benchmarker duration by half (5 seconds) and reduce the number of runs to 10 (from the default of 30) to get the results back in a reasonable amount of time, especially with the newly added benchmark parameter. This allowed me to finish benchmarking in a little over 4.5 hours, whereas before with the original duration and 30 runs it was still running after 18 hours (when it technically should have finished -- even taking into account overhead since a single run doesn't last exactly the duration specified).

With that being said, here are the results with those modified benchmarking settings:

                                                                                               improvement significant      p.value
 http/simple.js res="normal" c=50 chunks=0 length=1024 type="buffer" benchmarker="wrk"              7.32 %         *** 3.688222e-09
 http/simple.js res="normal" c=50 chunks=0 length=1024 type="bytes" benchmarker="wrk"               6.33 %         *** 2.198646e-07
 http/simple.js res="normal" c=50 chunks=0 length=102400 type="buffer" benchmarker="wrk"            5.98 %         *** 8.444083e-09
 http/simple.js res="normal" c=50 chunks=0 length=102400 type="bytes" benchmarker="wrk"             1.71 %             5.654903e-02
 http/simple.js res="normal" c=50 chunks=0 length=4 type="buffer" benchmarker="wrk"                 6.75 %         *** 4.882309e-06
 http/simple.js res="normal" c=50 chunks=0 length=4 type="bytes" benchmarker="wrk"                  8.36 %         *** 5.103912e-10
 http/simple.js res="normal" c=50 chunks=1 length=1024 type="buffer" benchmarker="wrk"              7.00 %         *** 5.923557e-08
 http/simple.js res="normal" c=50 chunks=1 length=1024 type="bytes" benchmarker="wrk"               5.91 %         *** 9.026994e-07
 http/simple.js res="normal" c=50 chunks=1 length=102400 type="buffer" benchmarker="wrk"            6.87 %         *** 5.115533e-10
 http/simple.js res="normal" c=50 chunks=1 length=102400 type="bytes" benchmarker="wrk"            -0.56 %             4.997734e-01
 http/simple.js res="normal" c=50 chunks=1 length=4 type="buffer" benchmarker="wrk"                 7.06 %         *** 9.929058e-07
 http/simple.js res="normal" c=50 chunks=1 length=4 type="bytes" benchmarker="wrk"                  7.99 %         *** 1.538373e-09
 http/simple.js res="normal" c=50 chunks=4 length=1024 type="buffer" benchmarker="wrk"              9.10 %         *** 1.348325e-07
 http/simple.js res="normal" c=50 chunks=4 length=1024 type="bytes" benchmarker="wrk"               0.23 %             5.229137e-01
 http/simple.js res="normal" c=50 chunks=4 length=102400 type="buffer" benchmarker="wrk"            7.51 %         *** 1.106307e-11
 http/simple.js res="normal" c=50 chunks=4 length=102400 type="bytes" benchmarker="wrk"             1.12 %             2.529282e-01
 http/simple.js res="normal" c=50 chunks=4 length=4 type="buffer" benchmarker="wrk"                 9.56 %         *** 9.803919e-09
 http/simple.js res="normal" c=50 chunks=4 length=4 type="bytes" benchmarker="wrk"                  0.06 %             8.710531e-01
 http/simple.js res="normal" c=500 chunks=0 length=1024 type="buffer" benchmarker="wrk"             7.50 %         *** 1.055653e-05
 http/simple.js res="normal" c=500 chunks=0 length=1024 type="bytes" benchmarker="wrk"              7.24 %         *** 6.617968e-08
 http/simple.js res="normal" c=500 chunks=0 length=102400 type="buffer" benchmarker="wrk"           5.83 %         *** 2.168064e-06
 http/simple.js res="normal" c=500 chunks=0 length=102400 type="bytes" benchmarker="wrk"            0.45 %             5.161448e-01
 http/simple.js res="normal" c=500 chunks=0 length=4 type="buffer" benchmarker="wrk"                8.66 %         *** 3.537589e-07
 http/simple.js res="normal" c=500 chunks=0 length=4 type="bytes" benchmarker="wrk"                 7.71 %         *** 1.655858e-06
 http/simple.js res="normal" c=500 chunks=1 length=1024 type="buffer" benchmarker="wrk"             5.22 %         *** 1.379880e-05
 http/simple.js res="normal" c=500 chunks=1 length=1024 type="bytes" benchmarker="wrk"              4.26 %         *** 1.961713e-06
 http/simple.js res="normal" c=500 chunks=1 length=102400 type="buffer" benchmarker="wrk"           7.52 %         *** 1.537612e-06
 http/simple.js res="normal" c=500 chunks=1 length=102400 type="bytes" benchmarker="wrk"            0.25 %             6.697942e-01
 http/simple.js res="normal" c=500 chunks=1 length=4 type="buffer" benchmarker="wrk"                7.42 %         *** 3.138037e-06
 http/simple.js res="normal" c=500 chunks=1 length=4 type="bytes" benchmarker="wrk"                 7.42 %         *** 2.934613e-06
 http/simple.js res="normal" c=500 chunks=4 length=1024 type="buffer" benchmarker="wrk"             7.27 %         *** 1.925539e-06
 http/simple.js res="normal" c=500 chunks=4 length=1024 type="bytes" benchmarker="wrk"              3.05 %         *** 3.470258e-06
 http/simple.js res="normal" c=500 chunks=4 length=102400 type="buffer" benchmarker="wrk"           8.53 %         *** 8.922735e-09
 http/simple.js res="normal" c=500 chunks=4 length=102400 type="bytes" benchmarker="wrk"            2.10 %           * 3.249854e-02
 http/simple.js res="normal" c=500 chunks=4 length=4 type="buffer" benchmarker="wrk"                9.68 %         *** 8.849623e-11
 http/simple.js res="normal" c=500 chunks=4 length=4 type="bytes" benchmarker="wrk"                 4.11 %         *** 2.105516e-04
 http/simple.js res="setHeader" c=50 chunks=0 length=1024 type="buffer" benchmarker="wrk"           8.17 %         *** 1.632875e-08
 http/simple.js res="setHeader" c=50 chunks=0 length=1024 type="bytes" benchmarker="wrk"            8.10 %         *** 3.557907e-08
 http/simple.js res="setHeader" c=50 chunks=0 length=102400 type="buffer" benchmarker="wrk"         5.60 %         *** 3.508730e-05
 http/simple.js res="setHeader" c=50 chunks=0 length=102400 type="bytes" benchmarker="wrk"          1.34 %           * 1.388335e-02
 http/simple.js res="setHeader" c=50 chunks=0 length=4 type="buffer" benchmarker="wrk"              8.41 %         *** 1.808168e-09
 http/simple.js res="setHeader" c=50 chunks=0 length=4 type="bytes" benchmarker="wrk"               7.22 %         *** 1.431984e-07
 http/simple.js res="setHeader" c=50 chunks=1 length=1024 type="buffer" benchmarker="wrk"           8.31 %         *** 8.101591e-08
 http/simple.js res="setHeader" c=50 chunks=1 length=1024 type="bytes" benchmarker="wrk"            6.02 %         *** 4.761886e-05
 http/simple.js res="setHeader" c=50 chunks=1 length=102400 type="buffer" benchmarker="wrk"         6.51 %         *** 3.062989e-07
 http/simple.js res="setHeader" c=50 chunks=1 length=102400 type="bytes" benchmarker="wrk"          0.24 %             7.525069e-01
 http/simple.js res="setHeader" c=50 chunks=1 length=4 type="buffer" benchmarker="wrk"              7.10 %         *** 1.525359e-06
 http/simple.js res="setHeader" c=50 chunks=1 length=4 type="bytes" benchmarker="wrk"               6.57 %         *** 8.604833e-09
 http/simple.js res="setHeader" c=50 chunks=4 length=1024 type="buffer" benchmarker="wrk"           9.10 %         *** 2.257903e-09
 http/simple.js res="setHeader" c=50 chunks=4 length=1024 type="bytes" benchmarker="wrk"           -0.59 %           * 3.725369e-02
 http/simple.js res="setHeader" c=50 chunks=4 length=102400 type="buffer" benchmarker="wrk"         8.10 %         *** 7.263169e-10
 http/simple.js res="setHeader" c=50 chunks=4 length=102400 type="bytes" benchmarker="wrk"          1.06 %             1.969950e-01
 http/simple.js res="setHeader" c=50 chunks=4 length=4 type="buffer" benchmarker="wrk"             11.29 %         *** 3.677319e-09
 http/simple.js res="setHeader" c=50 chunks=4 length=4 type="bytes" benchmarker="wrk"               0.72 %             5.166339e-02
 http/simple.js res="setHeader" c=500 chunks=0 length=1024 type="buffer" benchmarker="wrk"          8.78 %         *** 9.781154e-10
 http/simple.js res="setHeader" c=500 chunks=0 length=1024 type="bytes" benchmarker="wrk"           9.76 %         *** 1.518366e-10
 http/simple.js res="setHeader" c=500 chunks=0 length=102400 type="buffer" benchmarker="wrk"        6.38 %         *** 7.752881e-07
 http/simple.js res="setHeader" c=500 chunks=0 length=102400 type="bytes" benchmarker="wrk"         0.77 %             1.230367e-01
 http/simple.js res="setHeader" c=500 chunks=0 length=4 type="buffer" benchmarker="wrk"             5.72 %         *** 7.548957e-05
 http/simple.js res="setHeader" c=500 chunks=0 length=4 type="bytes" benchmarker="wrk"              7.88 %         *** 1.533032e-11
 http/simple.js res="setHeader" c=500 chunks=1 length=1024 type="buffer" benchmarker="wrk"          7.58 %         *** 7.720209e-08
 http/simple.js res="setHeader" c=500 chunks=1 length=1024 type="bytes" benchmarker="wrk"           6.57 %         *** 1.119938e-07
 http/simple.js res="setHeader" c=500 chunks=1 length=102400 type="buffer" benchmarker="wrk"        6.72 %         *** 6.689565e-07
 http/simple.js res="setHeader" c=500 chunks=1 length=102400 type="bytes" benchmarker="wrk"         1.32 %           * 2.304825e-02
 http/simple.js res="setHeader" c=500 chunks=1 length=4 type="buffer" benchmarker="wrk"             6.18 %         *** 2.418794e-06
 http/simple.js res="setHeader" c=500 chunks=1 length=4 type="bytes" benchmarker="wrk"              6.51 %         *** 4.905086e-05
 http/simple.js res="setHeader" c=500 chunks=4 length=1024 type="buffer" benchmarker="wrk"          7.99 %         *** 2.740359e-09
 http/simple.js res="setHeader" c=500 chunks=4 length=1024 type="bytes" benchmarker="wrk"           5.16 %         *** 2.070415e-06
 http/simple.js res="setHeader" c=500 chunks=4 length=102400 type="buffer" benchmarker="wrk"        8.49 %         *** 3.867745e-07
 http/simple.js res="setHeader" c=500 chunks=4 length=102400 type="bytes" benchmarker="wrk"         1.87 %          ** 4.240368e-03
 http/simple.js res="setHeader" c=500 chunks=4 length=4 type="buffer" benchmarker="wrk"             9.21 %         *** 3.996481e-09
 http/simple.js res="setHeader" c=500 chunks=4 length=4 type="bytes" benchmarker="wrk"              5.97 %         *** 6.721432e-09
 http/simple.js res="setHeaderWH" c=50 chunks=0 length=1024 type="buffer" benchmarker="wrk"         7.90 %         *** 1.810239e-07
 http/simple.js res="setHeaderWH" c=50 chunks=0 length=1024 type="bytes" benchmarker="wrk"          6.88 %         *** 3.428408e-06
 http/simple.js res="setHeaderWH" c=50 chunks=0 length=102400 type="buffer" benchmarker="wrk"       5.32 %         *** 2.453555e-07
 http/simple.js res="setHeaderWH" c=50 chunks=0 length=102400 type="bytes" benchmarker="wrk"        2.16 %           * 2.768038e-02
 http/simple.js res="setHeaderWH" c=50 chunks=0 length=4 type="buffer" benchmarker="wrk"            7.95 %         *** 4.600429e-08
 http/simple.js res="setHeaderWH" c=50 chunks=0 length=4 type="bytes" benchmarker="wrk"             9.72 %         *** 3.555558e-09
 http/simple.js res="setHeaderWH" c=50 chunks=1 length=1024 type="buffer" benchmarker="wrk"         6.85 %         *** 6.685907e-09
 http/simple.js res="setHeaderWH" c=50 chunks=1 length=1024 type="bytes" benchmarker="wrk"          6.59 %         *** 5.100999e-12
 http/simple.js res="setHeaderWH" c=50 chunks=1 length=102400 type="buffer" benchmarker="wrk"       5.98 %         *** 1.976488e-08
 http/simple.js res="setHeaderWH" c=50 chunks=1 length=102400 type="bytes" benchmarker="wrk"        0.34 %             7.409726e-01
 http/simple.js res="setHeaderWH" c=50 chunks=1 length=4 type="buffer" benchmarker="wrk"            7.10 %         *** 1.609698e-08
 http/simple.js res="setHeaderWH" c=50 chunks=1 length=4 type="bytes" benchmarker="wrk"             6.17 %         *** 4.184348e-06
 http/simple.js res="setHeaderWH" c=50 chunks=4 length=1024 type="buffer" benchmarker="wrk"         7.86 %         *** 1.076794e-08
 http/simple.js res="setHeaderWH" c=50 chunks=4 length=1024 type="bytes" benchmarker="wrk"         -0.17 %             6.353906e-01
 http/simple.js res="setHeaderWH" c=50 chunks=4 length=102400 type="buffer" benchmarker="wrk"       7.40 %         *** 1.169940e-08
 http/simple.js res="setHeaderWH" c=50 chunks=4 length=102400 type="bytes" benchmarker="wrk"        0.88 %             4.654874e-01
 http/simple.js res="setHeaderWH" c=50 chunks=4 length=4 type="buffer" benchmarker="wrk"            8.24 %         *** 1.181670e-08
 http/simple.js res="setHeaderWH" c=50 chunks=4 length=4 type="bytes" benchmarker="wrk"             0.06 %             8.565252e-01
 http/simple.js res="setHeaderWH" c=500 chunks=0 length=1024 type="buffer" benchmarker="wrk"        6.76 %         *** 2.827915e-08
 http/simple.js res="setHeaderWH" c=500 chunks=0 length=1024 type="bytes" benchmarker="wrk"         7.09 %         *** 2.026343e-07
 http/simple.js res="setHeaderWH" c=500 chunks=0 length=102400 type="buffer" benchmarker="wrk"      6.91 %         *** 1.757360e-08
 http/simple.js res="setHeaderWH" c=500 chunks=0 length=102400 type="bytes" benchmarker="wrk"       1.17 %             7.434941e-02
 http/simple.js res="setHeaderWH" c=500 chunks=0 length=4 type="buffer" benchmarker="wrk"           6.97 %         *** 4.805588e-06
 http/simple.js res="setHeaderWH" c=500 chunks=0 length=4 type="bytes" benchmarker="wrk"            7.47 %         *** 6.128214e-06
 http/simple.js res="setHeaderWH" c=500 chunks=1 length=1024 type="buffer" benchmarker="wrk"        6.13 %         *** 4.073914e-06
 http/simple.js res="setHeaderWH" c=500 chunks=1 length=1024 type="bytes" benchmarker="wrk"         5.01 %         *** 1.285283e-07
 http/simple.js res="setHeaderWH" c=500 chunks=1 length=102400 type="buffer" benchmarker="wrk"      6.72 %         *** 7.269783e-07
 http/simple.js res="setHeaderWH" c=500 chunks=1 length=102400 type="bytes" benchmarker="wrk"       1.74 %          ** 3.253656e-03
 http/simple.js res="setHeaderWH" c=500 chunks=1 length=4 type="buffer" benchmarker="wrk"           5.71 %         *** 3.753727e-05
 http/simple.js res="setHeaderWH" c=500 chunks=1 length=4 type="bytes" benchmarker="wrk"            5.92 %         *** 2.036796e-07
 http/simple.js res="setHeaderWH" c=500 chunks=4 length=1024 type="buffer" benchmarker="wrk"        8.42 %         *** 1.564555e-09
 http/simple.js res="setHeaderWH" c=500 chunks=4 length=1024 type="bytes" benchmarker="wrk"         4.12 %         *** 1.636968e-05
 http/simple.js res="setHeaderWH" c=500 chunks=4 length=102400 type="buffer" benchmarker="wrk"      8.30 %         *** 1.528112e-08
 http/simple.js res="setHeaderWH" c=500 chunks=4 length=102400 type="bytes" benchmarker="wrk"      -0.41 %             3.825369e-01
 http/simple.js res="setHeaderWH" c=500 chunks=4 length=4 type="buffer" benchmarker="wrk"           9.25 %         *** 3.030151e-11
 http/simple.js res="setHeaderWH" c=500 chunks=4 length=4 type="bytes" benchmarker="wrk"            5.56 %         *** 1.334783e-06


When adding 3 custom headers in the 'setHeaderWH' case for example, you can see a greater increase:

                                                                                               improvement significant      p.value
 http/simple.js res="normal" c=50 chunks=0 length=1024 type="buffer" benchmarker="wrk"              7.77 %         *** 1.601361e-05
 http/simple.js res="normal" c=50 chunks=0 length=1024 type="bytes" benchmarker="wrk"               9.08 %         *** 1.121818e-09
 http/simple.js res="normal" c=50 chunks=0 length=102400 type="buffer" benchmarker="wrk"            6.65 %         *** 1.661088e-05
 http/simple.js res="normal" c=50 chunks=0 length=102400 type="bytes" benchmarker="wrk"             0.63 %             3.675953e-01
 http/simple.js res="normal" c=50 chunks=0 length=4 type="buffer" benchmarker="wrk"                 6.36 %         *** 1.071347e-05
 http/simple.js res="normal" c=50 chunks=0 length=4 type="bytes" benchmarker="wrk"                  7.53 %         *** 1.164565e-07
 http/simple.js res="normal" c=50 chunks=1 length=1024 type="buffer" benchmarker="wrk"              7.89 %         *** 2.980547e-07
 http/simple.js res="normal" c=50 chunks=1 length=1024 type="bytes" benchmarker="wrk"               7.66 %         *** 8.650294e-08
 http/simple.js res="normal" c=50 chunks=1 length=102400 type="buffer" benchmarker="wrk"            6.14 %         *** 1.055995e-06
 http/simple.js res="normal" c=50 chunks=1 length=102400 type="bytes" benchmarker="wrk"             0.99 %             1.902222e-01
 http/simple.js res="normal" c=50 chunks=1 length=4 type="buffer" benchmarker="wrk"                 8.55 %         *** 9.155390e-10
 http/simple.js res="normal" c=50 chunks=1 length=4 type="bytes" benchmarker="wrk"                  6.76 %         *** 1.052775e-09
 http/simple.js res="normal" c=50 chunks=4 length=1024 type="buffer" benchmarker="wrk"              9.13 %         *** 2.542129e-08
 http/simple.js res="normal" c=50 chunks=4 length=1024 type="bytes" benchmarker="wrk"              -0.28 %             4.029347e-01
 http/simple.js res="normal" c=50 chunks=4 length=102400 type="buffer" benchmarker="wrk"            8.56 %         *** 1.195479e-09
 http/simple.js res="normal" c=50 chunks=4 length=102400 type="bytes" benchmarker="wrk"             3.24 %             1.101345e-01
 http/simple.js res="normal" c=50 chunks=4 length=4 type="buffer" benchmarker="wrk"                 8.85 %         *** 1.233388e-10
 http/simple.js res="normal" c=50 chunks=4 length=4 type="bytes" benchmarker="wrk"                 -0.06 %             8.685515e-01
 http/simple.js res="normal" c=500 chunks=0 length=1024 type="buffer" benchmarker="wrk"             8.42 %         *** 2.652444e-07
 http/simple.js res="normal" c=500 chunks=0 length=1024 type="bytes" benchmarker="wrk"              7.62 %         *** 1.331863e-06
 http/simple.js res="normal" c=500 chunks=0 length=102400 type="buffer" benchmarker="wrk"           6.48 %         *** 2.695242e-06
 http/simple.js res="normal" c=500 chunks=0 length=102400 type="bytes" benchmarker="wrk"            1.69 %          ** 6.529191e-03
 http/simple.js res="normal" c=500 chunks=0 length=4 type="buffer" benchmarker="wrk"                8.44 %         *** 8.656604e-10
 http/simple.js res="normal" c=500 chunks=0 length=4 type="bytes" benchmarker="wrk"                 8.50 %         *** 1.355492e-06
 http/simple.js res="normal" c=500 chunks=1 length=1024 type="buffer" benchmarker="wrk"             7.02 %         *** 9.199390e-06
 http/simple.js res="normal" c=500 chunks=1 length=1024 type="bytes" benchmarker="wrk"              5.14 %         *** 5.819643e-08
 http/simple.js res="normal" c=500 chunks=1 length=102400 type="buffer" benchmarker="wrk"           6.35 %         *** 1.255342e-06
 http/simple.js res="normal" c=500 chunks=1 length=102400 type="bytes" benchmarker="wrk"            0.18 %             6.315421e-01
 http/simple.js res="normal" c=500 chunks=1 length=4 type="buffer" benchmarker="wrk"                7.16 %         *** 9.359637e-07
 http/simple.js res="normal" c=500 chunks=1 length=4 type="bytes" benchmarker="wrk"                 9.56 %         *** 1.078578e-08
 http/simple.js res="normal" c=500 chunks=4 length=1024 type="buffer" benchmarker="wrk"             8.05 %         *** 5.406988e-08
 http/simple.js res="normal" c=500 chunks=4 length=1024 type="bytes" benchmarker="wrk"              6.16 %         *** 1.830028e-09
 http/simple.js res="normal" c=500 chunks=4 length=102400 type="buffer" benchmarker="wrk"           7.99 %         *** 3.395783e-07
 http/simple.js res="normal" c=500 chunks=4 length=102400 type="bytes" benchmarker="wrk"            1.44 %             1.194225e-01
 http/simple.js res="normal" c=500 chunks=4 length=4 type="buffer" benchmarker="wrk"                8.78 %         *** 1.523263e-09
 http/simple.js res="normal" c=500 chunks=4 length=4 type="bytes" benchmarker="wrk"                 5.10 %         *** 7.574540e-07
 http/simple.js res="setHeader" c=50 chunks=0 length=1024 type="buffer" benchmarker="wrk"           9.29 %         *** 1.280683e-08
 http/simple.js res="setHeader" c=50 chunks=0 length=1024 type="bytes" benchmarker="wrk"            9.95 %         *** 1.584752e-07
 http/simple.js res="setHeader" c=50 chunks=0 length=102400 type="buffer" benchmarker="wrk"         6.83 %         *** 1.742157e-08
 http/simple.js res="setHeader" c=50 chunks=0 length=102400 type="bytes" benchmarker="wrk"          1.38 %          ** 5.483820e-03
 http/simple.js res="setHeader" c=50 chunks=0 length=4 type="buffer" benchmarker="wrk"              8.05 %         *** 8.117180e-08
 http/simple.js res="setHeader" c=50 chunks=0 length=4 type="bytes" benchmarker="wrk"               8.39 %         *** 5.710765e-10
 http/simple.js res="setHeader" c=50 chunks=1 length=1024 type="buffer" benchmarker="wrk"           8.66 %         *** 1.183858e-08
 http/simple.js res="setHeader" c=50 chunks=1 length=1024 type="bytes" benchmarker="wrk"            5.46 %         *** 1.684719e-08
 http/simple.js res="setHeader" c=50 chunks=1 length=102400 type="buffer" benchmarker="wrk"         6.98 %         *** 1.822605e-09
 http/simple.js res="setHeader" c=50 chunks=1 length=102400 type="bytes" benchmarker="wrk"         -0.11 %             8.195283e-01
 http/simple.js res="setHeader" c=50 chunks=1 length=4 type="buffer" benchmarker="wrk"              8.25 %         *** 1.101647e-06
 http/simple.js res="setHeader" c=50 chunks=1 length=4 type="bytes" benchmarker="wrk"               7.55 %         *** 3.233031e-06
 http/simple.js res="setHeader" c=50 chunks=4 length=1024 type="buffer" benchmarker="wrk"           9.50 %         *** 6.194324e-09
 http/simple.js res="setHeader" c=50 chunks=4 length=1024 type="bytes" benchmarker="wrk"            0.44 %             2.160161e-01
 http/simple.js res="setHeader" c=50 chunks=4 length=102400 type="buffer" benchmarker="wrk"         9.00 %         *** 2.026993e-10
 http/simple.js res="setHeader" c=50 chunks=4 length=102400 type="bytes" benchmarker="wrk"          3.13 %          ** 1.171021e-03
 http/simple.js res="setHeader" c=50 chunks=4 length=4 type="buffer" benchmarker="wrk"              8.65 %         *** 2.244983e-07
 http/simple.js res="setHeader" c=50 chunks=4 length=4 type="bytes" benchmarker="wrk"               0.51 %             9.793385e-02
 http/simple.js res="setHeader" c=500 chunks=0 length=1024 type="buffer" benchmarker="wrk"          6.55 %         *** 1.372787e-05
 http/simple.js res="setHeader" c=500 chunks=0 length=1024 type="bytes" benchmarker="wrk"           9.26 %         *** 3.045767e-10
 http/simple.js res="setHeader" c=500 chunks=0 length=102400 type="buffer" benchmarker="wrk"        6.96 %         *** 9.700479e-06
 http/simple.js res="setHeader" c=500 chunks=0 length=102400 type="bytes" benchmarker="wrk"         0.93 %             5.513154e-02
 http/simple.js res="setHeader" c=500 chunks=0 length=4 type="buffer" benchmarker="wrk"             7.92 %         *** 9.842509e-07
 http/simple.js res="setHeader" c=500 chunks=0 length=4 type="bytes" benchmarker="wrk"              8.26 %         *** 2.497220e-07
 http/simple.js res="setHeader" c=500 chunks=1 length=1024 type="buffer" benchmarker="wrk"          6.43 %         *** 3.543546e-05
 http/simple.js res="setHeader" c=500 chunks=1 length=1024 type="bytes" benchmarker="wrk"           5.06 %         *** 3.949956e-06
 http/simple.js res="setHeader" c=500 chunks=1 length=102400 type="buffer" benchmarker="wrk"        8.19 %         *** 1.144397e-07
 http/simple.js res="setHeader" c=500 chunks=1 length=102400 type="bytes" benchmarker="wrk"         1.08 %          ** 4.206755e-03
 http/simple.js res="setHeader" c=500 chunks=1 length=4 type="buffer" benchmarker="wrk"             6.50 %         *** 1.028961e-07
 http/simple.js res="setHeader" c=500 chunks=1 length=4 type="bytes" benchmarker="wrk"              8.16 %         *** 1.984112e-10
 http/simple.js res="setHeader" c=500 chunks=4 length=1024 type="buffer" benchmarker="wrk"          8.34 %         *** 1.201055e-09
 http/simple.js res="setHeader" c=500 chunks=4 length=1024 type="bytes" benchmarker="wrk"           4.56 %         *** 3.211769e-06
 http/simple.js res="setHeader" c=500 chunks=4 length=102400 type="buffer" benchmarker="wrk"       10.43 %         *** 5.400673e-09
 http/simple.js res="setHeader" c=500 chunks=4 length=102400 type="bytes" benchmarker="wrk"         2.24 %           * 3.267481e-02
 http/simple.js res="setHeader" c=500 chunks=4 length=4 type="buffer" benchmarker="wrk"             9.89 %         *** 7.214477e-09
 http/simple.js res="setHeader" c=500 chunks=4 length=4 type="bytes" benchmarker="wrk"              5.40 %         *** 1.465118e-05
 http/simple.js res="setHeaderWH" c=50 chunks=0 length=1024 type="buffer" benchmarker="wrk"        10.52 %         *** 8.904727e-10
 http/simple.js res="setHeaderWH" c=50 chunks=0 length=1024 type="bytes" benchmarker="wrk"         10.94 %         *** 2.688616e-10
 http/simple.js res="setHeaderWH" c=50 chunks=0 length=102400 type="buffer" benchmarker="wrk"       9.00 %         *** 6.729648e-09
 http/simple.js res="setHeaderWH" c=50 chunks=0 length=102400 type="bytes" benchmarker="wrk"        1.81 %          ** 7.444911e-03
 http/simple.js res="setHeaderWH" c=50 chunks=0 length=4 type="buffer" benchmarker="wrk"           11.95 %         *** 7.684982e-11
 http/simple.js res="setHeaderWH" c=50 chunks=0 length=4 type="bytes" benchmarker="wrk"            13.92 %         *** 8.301877e-11
 http/simple.js res="setHeaderWH" c=50 chunks=1 length=1024 type="buffer" benchmarker="wrk"        10.40 %         *** 3.490284e-09
 http/simple.js res="setHeaderWH" c=50 chunks=1 length=1024 type="bytes" benchmarker="wrk"         10.40 %         *** 5.392976e-11
 http/simple.js res="setHeaderWH" c=50 chunks=1 length=102400 type="buffer" benchmarker="wrk"       9.55 %         *** 1.432894e-09
 http/simple.js res="setHeaderWH" c=50 chunks=1 length=102400 type="bytes" benchmarker="wrk"        2.11 %           * 1.452478e-02
 http/simple.js res="setHeaderWH" c=50 chunks=1 length=4 type="buffer" benchmarker="wrk"           11.19 %         *** 3.085235e-13
 http/simple.js res="setHeaderWH" c=50 chunks=1 length=4 type="bytes" benchmarker="wrk"            10.91 %         *** 2.346356e-11
 http/simple.js res="setHeaderWH" c=50 chunks=4 length=1024 type="buffer" benchmarker="wrk"        12.13 %         *** 5.259254e-13
 http/simple.js res="setHeaderWH" c=50 chunks=4 length=1024 type="bytes" benchmarker="wrk"          0.15 %             7.129618e-01
 http/simple.js res="setHeaderWH" c=50 chunks=4 length=102400 type="buffer" benchmarker="wrk"      10.40 %         *** 1.480122e-10
 http/simple.js res="setHeaderWH" c=50 chunks=4 length=102400 type="bytes" benchmarker="wrk"        1.51 %             1.786063e-01
 http/simple.js res="setHeaderWH" c=50 chunks=4 length=4 type="buffer" benchmarker="wrk"           11.76 %         *** 2.442914e-10
 http/simple.js res="setHeaderWH" c=50 chunks=4 length=4 type="bytes" benchmarker="wrk"             0.40 %             2.534618e-01
 http/simple.js res="setHeaderWH" c=500 chunks=0 length=1024 type="buffer" benchmarker="wrk"       10.31 %         *** 3.108517e-06
 http/simple.js res="setHeaderWH" c=500 chunks=0 length=1024 type="bytes" benchmarker="wrk"        11.50 %         *** 3.775474e-09
 http/simple.js res="setHeaderWH" c=500 chunks=0 length=102400 type="buffer" benchmarker="wrk"      7.27 %         *** 2.105709e-05
 http/simple.js res="setHeaderWH" c=500 chunks=0 length=102400 type="bytes" benchmarker="wrk"       1.86 %           * 2.036897e-02
 http/simple.js res="setHeaderWH" c=500 chunks=0 length=4 type="buffer" benchmarker="wrk"           9.54 %         *** 7.382276e-09
 http/simple.js res="setHeaderWH" c=500 chunks=0 length=4 type="bytes" benchmarker="wrk"           10.39 %         *** 3.321337e-09
 http/simple.js res="setHeaderWH" c=500 chunks=1 length=1024 type="buffer" benchmarker="wrk"        9.89 %         *** 7.341164e-09
 http/simple.js res="setHeaderWH" c=500 chunks=1 length=1024 type="bytes" benchmarker="wrk"        11.74 %         *** 2.112175e-12
 http/simple.js res="setHeaderWH" c=500 chunks=1 length=102400 type="buffer" benchmarker="wrk"      9.05 %         *** 1.937033e-09
 http/simple.js res="setHeaderWH" c=500 chunks=1 length=102400 type="bytes" benchmarker="wrk"       0.78 %             1.559825e-01
 http/simple.js res="setHeaderWH" c=500 chunks=1 length=4 type="buffer" benchmarker="wrk"          10.72 %         *** 4.013310e-10
 http/simple.js res="setHeaderWH" c=500 chunks=1 length=4 type="bytes" benchmarker="wrk"            7.99 %         *** 1.059505e-07
 http/simple.js res="setHeaderWH" c=500 chunks=4 length=1024 type="buffer" benchmarker="wrk"       11.64 %         *** 1.544061e-10
 http/simple.js res="setHeaderWH" c=500 chunks=4 length=1024 type="bytes" benchmarker="wrk"         6.84 %         *** 5.051422e-09
 http/simple.js res="setHeaderWH" c=500 chunks=4 length=102400 type="buffer" benchmarker="wrk"      9.51 %         *** 1.195116e-10
 http/simple.js res="setHeaderWH" c=500 chunks=4 length=102400 type="bytes" benchmarker="wrk"       3.65 %         *** 2.064001e-06
 http/simple.js res="setHeaderWH" c=500 chunks=4 length=4 type="buffer" benchmarker="wrk"          12.36 %         *** 9.105549e-11
 http/simple.js res="setHeaderWH" c=500 chunks=4 length=4 type="bytes" benchmarker="wrk"            6.36 %         *** 6.586488e-07


/cc @nodejs/http
/cc @nodejs/streams for stream changes
CI: https://ci.nodejs.org/job/node-test-pull-request/5651/
CI: https://ci.nodejs.org/job/node-test-pull-request/5652/

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

@mscdex mscdex added http Issues or PRs related to the http subsystem. stream Issues and PRs related to the stream subsystem. labels Dec 31, 2016
@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. dont-land-on-v7.x labels Dec 31, 2016
@mscdex mscdex added benchmark Issues and PRs related to the benchmark subsystem. and removed dont-land-on-v7.x lib / src Issues and PRs related to general changes in the lib or src directory. labels Dec 31, 2016
@mscdex mscdex added performance Issues and PRs related to the performance of Node.js. and removed dont-land-on-v7.x labels Jan 1, 2017
exports.chunkExpression = /chunk/i;
exports.continueExpression = /100-continue/i;
exports.chunkExpression = /(?:^|\W)chunked(?:$|\W)/i;
exports.continueExpression = /(?:^|\W)100-continue(?:$|\W)/i;
Copy link
Member

Choose a reason for hiding this comment

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

why those changes? are they faster, or safer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's more explicit and therefore at least a little safer and it's consistent with the other regexps we use in _http_server.js when searching header values that can be comma-separated lists.

I did not measure the performance of this particular change on its own.

this.corkedRequestsFree = new CorkedRequest(this);
var corkReq = { next: null, entry: null, finish: undefined };
corkReq.finish = onCorkedFinish.bind(undefined, corkReq, this);
this.corkedRequestsFree = corkReq;
Copy link
Member

Choose a reason for hiding this comment

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

Is this giving any perf increase? The major benefit is to avoid the creation of CorkedRequest, which was introduced to leverage hidden classes and the like.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. This is similar to what was done awhile back for process.nextTick() request objects, changed from new Foo() to plain object.

encoding = 'buffer';
chunk = newChunk;
}
Copy link
Member

Choose a reason for hiding this comment

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

clever! nice catch!

encoding: encoding,
callback: cb,
next: null
};
Copy link
Member

Choose a reason for hiding this comment

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

we can probably reduce a bit the code footprint here by using:

{  chunk, encoding, callback: cb, next: null }

Not sure if this functions was inlineable before and/or this change remove that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought about that, but wasn't sure if that would cause compatibility problems for readable-stream users or if the babel transforms took care of that or what...

Copy link
Member

Choose a reason for hiding this comment

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

I think so, babel can/will take care of that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

@@ -113,7 +106,9 @@ function WritableState(options, stream) {

// allocate the first CorkedRequest, there is always
// one allocated and free to use, and we maintain at most two
this.corkedRequestsFree = new CorkedRequest(this);
var corkReq = { next: null, entry: null, finish: undefined };
corkReq.finish = onCorkedFinish.bind(undefined, corkReq, this);
Copy link
Member

Choose a reason for hiding this comment

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

can you please update the build script in readable-stream  when this lands too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

LGTM

@@ -129,8 +129,12 @@ function ClientRequest(options, cb) {
self._storeHeader(self.method + ' ' + self.path + ' HTTP/1.1\r\n',
options.headers);
} else if (self.getHeader('expect')) {
if (self._header) {
throw new Error('Can\'t render headers after they are sent to the ' +
Copy link
Contributor

Choose a reason for hiding this comment

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

This additional throw probably makes this PR semver-major?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It shouldn't, I just had to move the check from the old _renderHeaders() to the appropriate call sites since that function no longer exists. I tried just moving it to _storeHeader() but that caused problems IIRC.

@@ -218,8 +222,11 @@ ClientRequest.prototype._finish = function _finish() {
};

ClientRequest.prototype._implicitHeader = function _implicitHeader() {
if (this._header) {
throw new Error('Can\'t render headers after they are sent to the client');
Copy link
Contributor

Choose a reason for hiding this comment

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

As does this one

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It shouldn't, I just had to move the check from the old _renderHeaders() to the appropriate call sites since that function no longer exists. I tried just moving it to _storeHeader() but that caused problems IIRC.

var low = false;
while (true) {
switch (field) {
case 'Content-Type':
Copy link
Contributor

Choose a reason for hiding this comment

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

I surprisingly see Content-type and Content-length in the wild a ton. It may be useful to add those as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had to stop somewhere, plus you can only have a switch statement so large before the function gets deopt'ed (I think this may still be the case anyway).

Copy link
Contributor

@ronkorving ronkorving Jan 6, 2017

Choose a reason for hiding this comment

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

Is it not faster (and more elegant imho) to have a lookup object?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

From my testing it isn't faster, whether with a plain object or Map.

field = entry[0];
value = entry[1];

if (value instanceof Array) {
Copy link
Contributor

Choose a reason for hiding this comment

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

is it safe to use instanceof here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should be, since we're the ones storing header values in this._headers. That's also the reason why we can use for-in instead of Object.keys() (slight speedup there) when iterating over this._headers.

@@ -388,7 +419,10 @@ OutgoingMessage.prototype.getHeader = function getHeader(name) {

if (!this._headers) return;

return this._headers[name.toLowerCase()];
var entry = this._headers[name.toLowerCase()];
Copy link
Contributor

Choose a reason for hiding this comment

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

should we not use similar logic as in matchKnownFields here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't recall specifically if I tested it in here or not, but in some places such functions didn't seem to perform as well for whatever reason.

if (obj) {
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var k = keys[i];
k = keys[i];
Copy link
Contributor

Choose a reason for hiding this comment

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

did this change actually make a perf impact?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It wasn't about performance but easier readability and because I check if the loop was entered below by checking k.

Copy link
Contributor

Choose a reason for hiding this comment

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

ah ok, that makes sense

var fixed = 'C'.repeat(20 * 1024);
var storedBytes = Object.create(null);
var storedBuffer = Object.create(null);
var storedUnicode = Object.create(null);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can these be Maps instead? Also, let?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

AFAIK Map is still slow and http benchmarks already take a very long time as it is.

As far as converting to ES6 goes, that's for a separate PR I think. All I was doing in this part here was the changing style.

Copy link
Contributor

Choose a reason for hiding this comment

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

AFAIK Map is still slow and http benchmarks already take a very long time as it is.

That is why we have https://github.com/nodejs/node/blob/master/benchmark/es/map-bench.js - tl;dr, it's faster.

Copy link
Member

Choose a reason for hiding this comment

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

Map performance definitely appears to have improved significantly as of late.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, but I seem to recall some issue with that benchmark. I think there was discussion in some issue/PR awhile ago about it?

@jasnell
Copy link
Member

jasnell commented Jan 5, 2017

@mscdex ... looks like this needs a rebase

@mscdex
Copy link
Contributor Author

mscdex commented Jan 5, 2017

@mscdex mscdex added dont-land-on-v7.x semver-major PRs that contain breaking changes and should be released in the next major version. labels Jan 13, 2017
@mscdex
Copy link
Contributor Author

mscdex commented Jan 13, 2017

/cc @nodejs/ctc

I'm now marking this as semver-major because I just realized I forgot to run citgm and I just found out that there are apparently users (at least on github) that are using res._headerNames without checking its value first and/or making assumptions about the property values on res._headers, both of which changed in this PR.

So far the only instance on citgm where I ran into this is express, which uses the fresh module which makes assumptions about res._headers values. I will be submitting a PR to that project ASAP (EDIT: jshttp/fresh#20).

@ChALkeR Could you find out how many other modules on npm may be affected?

I really apologize for all of this....

@mscdex
Copy link
Contributor Author

mscdex commented Jan 14, 2017

I've now submitted a PR that should help resolve the main use cases for end users accessing ._headers in the first place: #10805

Since IIRC we don't have an official policy on undocumented, "private" (underscore-prefixed) properties yet, it would be good to hear what others think should be the way forward on this. Some ideas:

  • Land http: add new functions to OutgoingMessage #10805 and backport it to the LTS branches ASAP and this PR is only included in node v8.0.0+.
  • Temporarily revert the changes to ._headers for one full major version to give users more time to convert over to the .getHeaders() API. This means the re-landing of the original changes would happen in node v9.0.0. This solution would probably require us to really get the word out if there is as much possible breakage as there may seem to be.
  • Switch the current ._headers to some other name and make ._headers a getter that results in a deprecation warning (directing them to .getHeaders()) but still returns the value using the new property. This might make it less semver-major-y and would probably cause less breakage.

As far as the now removed ._headerNames goes, we could do like option 3 above and re-add it as a getter that results in a deprecation warning but still returns the original cased name now stored in ._headers. However I don't know if using getters like this would break anyone still or not (again, it's also an undocumented, "private" property, so how much do we care?) or at least to a lesser degree. Also, I am going to go out on a limb and say that ._headerNames usage is probably much less than ._headers usage in the wild.

@evanlucas
Copy link
Contributor

considering that fresh was downloaded 309,483 times in the last day, I think we should revert (quickly) and then re-evaluate. I would think that there are way too many people depending on older versions of express for us to revert this.

italoacasas pushed a commit to italoacasas/node that referenced this pull request Jan 18, 2017
PR-URL: nodejs#10558
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
italoacasas pushed a commit to italoacasas/node that referenced this pull request Jan 18, 2017
By enforcing the statusCode to be an SMI, it helps a bit
performance-wise when looking up the associated statusMessage.

PR-URL: nodejs#10558
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
italoacasas pushed a commit to italoacasas/node that referenced this pull request Jan 18, 2017
This commit implements two optimizations when working with headers:

* Avoid having to explicitly "render" headers and separately store the
original casing for header names.

* Match special header names using a single regular expression instead
of testing one regular expression per header name.

PR-URL: nodejs#10558
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
italoacasas pushed a commit to italoacasas/node that referenced this pull request Jan 18, 2017
PR-URL: nodejs#10558
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
italoacasas pushed a commit to italoacasas/node that referenced this pull request Jan 18, 2017
PR-URL: nodejs#10558
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
italoacasas pushed a commit to italoacasas/node that referenced this pull request Jan 18, 2017
PR-URL: nodejs#10558
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
italoacasas pushed a commit to italoacasas/node that referenced this pull request Jan 18, 2017
Without this, the http benchmarker would report "strange output" if
wrk or any other http client reported 0 requests per second, which is
a valid result.

PR-URL: nodejs#10558
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
italoacasas pushed a commit to italoacasas/node that referenced this pull request Jan 18, 2017
This is similar to a change made awhile back for storing
process.nextTick() requests.

PR-URL: nodejs#10558
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
italoacasas pushed a commit to italoacasas/node that referenced this pull request Jan 18, 2017
PR-URL: nodejs#10558
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
@mscdex
Copy link
Contributor Author

mscdex commented Jan 20, 2017

Any feedback from additional @nodejs/ctc members? Especially on any of the solutions I've proposed?

@bnoordhuis
Copy link
Member

Switch the current ._headers to some other name and make ._headers a getter that results in a deprecation warning (directing them to .getHeaders()) but still returns the value using the new property.

That sounds like a nice enough solution. Warn in v8.x and remove in v9.x?

@dougwilson
Copy link
Member

So to give a little detail here from Express side, the ._headers usage in Express is mainly used in the conditional response logic, and it's location is at the heart of the Express code paths for almost every version of Express ever released so far. I would venture to guess almost every Express app out there is running over this code path.

@mscdex made some PRs and we are working to iron out some edge cases, but when Express does release a version that does not reference ._headers there is certainly many years of versions out there that do. I can say from user support that it is very common for people not to be using the latest version of Express, even when the latest version has been out for over half a year, but I don't really know what percentage of those users end up on a new version of Express.

My thoughts are that if 8.x is going to become the next LTS, it would be really nice if the warning / removal started in a non-LTS version based on the rate it seems people upgrade Express. From the past, even a warning will end up having a lot of fallout from confused users all over the place, so just brainstorming how can we have the best chance for the change to go out unnoticed by the vast majority of the users.

@mscdex
Copy link
Contributor Author

mscdex commented Jan 21, 2017

Alright, I have proposed a getter-based solution in #10941.

@evanlucas
Copy link
Contributor

I am still +1 for reverting fwiw. I think we need to investigate better how this impacts the ecosystem especially considering that citgm is broken with this change...

@mscdex
Copy link
Contributor Author

mscdex commented Feb 20, 2017

@evanlucas If at least one other @nodejs/ctc member LGTM's #10941 then it shouldn't be an issue anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
benchmark Issues and PRs related to the benchmark subsystem. http Issues or PRs related to the http subsystem. performance Issues and PRs related to the performance of Node.js. semver-major PRs that contain breaking changes and should be released in the next major version. stream Issues and PRs related to the stream subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants