Skip to content

Conversation

BrennanConroy
Copy link
Member

Closes #49223

Continuation of #51426

This PR removes boyer-moore entirely in favor of the vectorized IndexOf method. This removes an int[256] alloc per section of the multipart data, as well as the construction cost of generating the skip table.

Additionally, noticed the MultipartBoundary class was allocating the boundary bytes array twice per use. The only difference between the arrays is one has \r\n at the beginning, so we can avoid the second alloc by always using the larger array and slicing.

Before:

Method BoundarySize SectionCount LargePayload Mean Error StdDev Median Op/s Gen 0 Gen 1 Gen 2 Allocated
MultipartReaderParsing 6 1 False 1.817 us 0.0173 us 0.0153 us 1.819 us 550,241.2 0.0477 - - 8 KB
MultipartReaderParsingWithRead 6 1 False 1.782 us 0.0224 us 0.0198 us 1.777 us 561,081.8 0.0477 - - 8 KB
MultipartReaderParsing 6 1 True 8,314.925 us 145.2528 us 135.8696 us 8,251.612 us 120.3 - - - 8 KB
MultipartReaderParsingWithRead 6 1 True 6,894.136 us 61.4071 us 54.4358 us 6,873.077 us 145.1 - - - 8 KB
MultipartReaderParsing 6 2 False 2.867 us 0.0416 us 0.0347 us 2.855 us 348,780.2 0.0648 - - 10 KB
MultipartReaderParsingWithRead 6 2 False 2.701 us 0.0352 us 0.0329 us 2.694 us 370,255.0 0.0610 - - 10 KB
MultipartReaderParsing 6 2 True 8,155.037 us 42.8945 us 33.4892 us 8,159.663 us 122.6 - - - 10 KB
MultipartReaderParsingWithRead 6 2 True 6,932.405 us 83.4595 us 69.6924 us 6,914.277 us 144.3 - - - 10 KB
MultipartReaderParsing 6 3 False 4.042 us 0.0797 us 0.0886 us 4.036 us 247,413.7 0.0763 - - 13 KB
MultipartReaderParsingWithRead 6 3 False 3.809 us 0.0752 us 0.0836 us 3.775 us 262,502.6 0.0763 - - 13 KB
MultipartReaderParsing 6 3 True 8,368.990 us 166.9362 us 156.1522 us 8,330.309 us 119.5 - - - 13 KB
MultipartReaderParsingWithRead 6 3 True 6,979.504 us 117.6382 us 172.4325 us 6,900.845 us 143.3 - - - 13 KB
MultipartReaderParsing 28 1 False 2.069 us 0.0265 us 0.0248 us 2.059 us 483,375.7 0.0496 - - 8 KB
MultipartReaderParsingWithRead 28 1 False 1.955 us 0.0359 us 0.0280 us 1.948 us 511,404.0 0.0458 - - 8 KB
MultipartReaderParsing 28 1 True 2,093.895 us 31.6270 us 28.0365 us 2,085.176 us 477.6 - - - 8 KB
MultipartReaderParsingWithRead 28 1 True 1,488.549 us 16.7059 us 13.0429 us 1,482.657 us 671.8 - - - 8 KB
MultipartReaderParsing 28 2 False 3.068 us 0.0307 us 0.0287 us 3.067 us 325,911.5 0.0648 - - 10 KB
MultipartReaderParsingWithRead 28 2 False 2.877 us 0.0344 us 0.0305 us 2.870 us 347,609.4 0.0610 - - 10 KB
MultipartReaderParsing 28 2 True 1,991.692 us 16.2931 us 13.6055 us 1,992.189 us 502.1 - - - 10 KB
MultipartReaderParsingWithRead 28 2 True 1,495.973 us 20.0640 us 16.7543 us 1,498.211 us 668.5 - - - 10 KB
MultipartReaderParsing 28 3 False 4.162 us 0.0748 us 0.0624 us 4.151 us 240,272.1 0.0763 - - 13 KB
MultipartReaderParsingWithRead 28 3 False 3.964 us 0.0568 us 0.0558 us 3.953 us 252,242.5 0.0763 - - 13 KB
MultipartReaderParsing 28 3 True 1,942.813 us 14.0343 us 11.7193 us 1,941.072 us 514.7 - - - 13 KB
MultipartReaderParsingWithRead 28 3 True 1,505.530 us 13.0859 us 11.6003 us 1,501.354 us 664.2 - - - 13 KB
MultipartReaderParsing 70 1 False 2.376 us 0.0295 us 0.0276 us 2.363 us 420,814.8 0.0496 - - 8 KB
MultipartReaderParsingWithRead 70 1 False 2.262 us 0.0327 us 0.0290 us 2.252 us 442,087.9 0.0496 - - 8 KB
MultipartReaderParsing 70 1 True 1,596.894 us 21.6602 us 20.2610 us 1,597.104 us 626.2 - - - 8 KB
MultipartReaderParsingWithRead 70 1 True 1,119.535 us 15.8749 us 12.3941 us 1,118.530 us 893.2 - - - 8 KB
MultipartReaderParsing 70 2 False 3.281 us 0.0376 us 0.0352 us 3.279 us 304,823.6 0.0648 - - 11 KB
MultipartReaderParsingWithRead 70 2 False 3.243 us 0.0381 us 0.0356 us 3.228 us 308,343.7 0.0648 - - 10 KB
MultipartReaderParsing 70 2 True 1,486.637 us 17.9004 us 14.9476 us 1,481.462 us 672.7 - - - 11 KB
MultipartReaderParsingWithRead 70 2 True 1,069.610 us 7.3609 us 5.7469 us 1,067.528 us 934.9 - - - 10 KB
MultipartReaderParsing 70 3 False 4.581 us 0.0705 us 0.0659 us 4.548 us 218,289.2 0.0763 - - 13 KB
MultipartReaderParsingWithRead 70 3 False 4.362 us 0.0448 us 0.0397 us 4.349 us 229,260.2 0.0763 - - 13 KB
MultipartReaderParsing 70 3 True 1,500.960 us 29.7081 us 27.7890 us 1,500.434 us 666.2 - - - 13 KB
MultipartReaderParsingWithRead 70 3 True 1,107.042 us 21.4795 us 41.8940 us 1,086.033 us 903.3 - - - 13 KB

After:

Method BoundarySize SectionCount LargePayload Mean Error StdDev Median Op/s Gen 0 Gen 1 Gen 2 Allocated
MultipartReaderParsing 6 1 False 1.499 us 0.0155 us 0.0145 us 1.495 us 667,251.0 0.0401 - - 7 KB
MultipartReaderParsingWithRead 6 1 False 1.452 us 0.0183 us 0.0162 us 1.446 us 688,936.0 0.0401 - - 7 KB
MultipartReaderParsing 6 1 True 1,027.257 us 19.8591 us 17.6046 us 1,024.243 us 973.5 - - - 7 KB
MultipartReaderParsingWithRead 6 1 True 743.071 us 8.9823 us 7.0128 us 743.726 us 1,345.8 - - - 7 KB
MultipartReaderParsing 6 2 False 2.575 us 0.0482 us 0.0473 us 2.562 us 388,320.6 0.0572 - - 9 KB
MultipartReaderParsingWithRead 6 2 False 2.546 us 0.0323 us 0.0269 us 2.541 us 392,736.2 0.0572 - - 9 KB
MultipartReaderParsing 6 2 True 1,028.504 us 13.2911 us 11.7822 us 1,026.482 us 972.3 - - - 9 KB
MultipartReaderParsingWithRead 6 2 True 758.341 us 11.2307 us 9.3782 us 755.808 us 1,318.7 - - - 9 KB
MultipartReaderParsing 6 3 False 3.404 us 0.0281 us 0.0249 us 3.402 us 293,786.1 0.0725 - - 12 KB
MultipartReaderParsingWithRead 6 3 False 3.275 us 0.0356 us 0.0278 us 3.267 us 305,382.1 0.0687 - - 11 KB
MultipartReaderParsing 6 3 True 1,093.334 us 21.3973 us 24.6412 us 1,089.587 us 914.6 - - - 12 KB
MultipartReaderParsingWithRead 6 3 True 1,062.086 us 61.2799 us 178.7563 us 1,053.938 us 941.5 - - - 11 KB
MultipartReaderParsing 28 1 False 1.577 us 0.0218 us 0.0182 us 1.576 us 634,011.1 0.0420 - - 7 KB
MultipartReaderParsingWithRead 28 1 False 1.539 us 0.0272 us 0.0241 us 1.541 us 649,960.3 0.0401 - - 7 KB
MultipartReaderParsing 28 1 True 1,145.681 us 22.8790 us 24.4802 us 1,145.504 us 872.8 - - - 7 KB
MultipartReaderParsingWithRead 28 1 True 927.021 us 17.6713 us 21.7020 us 926.486 us 1,078.7 - - - 7 KB
MultipartReaderParsing 28 2 False 2.711 us 0.0351 us 0.0328 us 2.713 us 368,805.4 0.0572 - - 9 KB
MultipartReaderParsingWithRead 28 2 False 2.609 us 0.0494 us 0.0462 us 2.603 us 383,225.2 0.0572 - - 9 KB
MultipartReaderParsing 28 2 True 1,123.515 us 21.4154 us 23.8032 us 1,119.464 us 890.1 - - - 9 KB
MultipartReaderParsingWithRead 28 2 True 907.002 us 17.3706 us 16.2485 us 905.688 us 1,102.5 - - - 9 KB
MultipartReaderParsing 28 3 False 3.550 us 0.0662 us 0.0553 us 3.554 us 281,693.7 0.0725 - - 12 KB
MultipartReaderParsingWithRead 28 3 False 3.365 us 0.0489 us 0.0408 us 3.366 us 297,146.2 0.0725 - - 12 KB
MultipartReaderParsing 28 3 True 1,200.989 us 23.7499 us 25.4121 us 1,198.623 us 832.6 - - - 12 KB
MultipartReaderParsingWithRead 28 3 True 1,196.509 us 55.5144 us 163.6854 us 1,193.885 us 835.8 - - - 12 KB
MultipartReaderParsing 70 1 False 1.775 us 0.0564 us 0.1553 us 1.720 us 563,292.0 0.0420 - - 7 KB
MultipartReaderParsingWithRead 70 1 False 1.945 us 0.0967 us 0.2853 us 1.944 us 514,136.7 0.0420 - - 7 KB
MultipartReaderParsing 70 1 True 1,228.408 us 24.0653 us 32.9409 us 1,217.490 us 814.1 - - - 7 KB
MultipartReaderParsingWithRead 70 1 True 1,106.088 us 15.0953 us 12.6053 us 1,105.808 us 904.1 - - - 7 KB
MultipartReaderParsing 70 2 False 2.646 us 0.0325 us 0.0272 us 2.656 us 377,958.2 0.0572 - - 9 KB
MultipartReaderParsingWithRead 70 2 False 2.718 us 0.0519 us 0.0510 us 2.712 us 367,908.4 0.0572 - - 9 KB
MultipartReaderParsing 70 2 True 1,233.603 us 22.1762 us 25.5381 us 1,234.265 us 810.6 - - - 9 KB
MultipartReaderParsingWithRead 70 2 True 1,097.775 us 20.9341 us 20.5601 us 1,090.971 us 910.9 - - - 9 KB
MultipartReaderParsing 70 3 False 3.540 us 0.0476 us 0.0445 us 3.532 us 282,502.1 0.0725 - - 12 KB
MultipartReaderParsingWithRead 70 3 False 3.398 us 0.0529 us 0.0469 us 3.395 us 294,294.8 0.0725 - - 12 KB
MultipartReaderParsing 70 3 True 1,316.488 us 23.5004 us 20.8325 us 1,313.648 us 759.6 - - - 12 KB
MultipartReaderParsingWithRead 70 3 True 1,106.403 us 21.5075 us 22.0867 us 1,098.645 us 903.8 - - - 12 KB

Highlights:
When the boundary size was small (6) and the payload was large (10m+ bytes) the RPS was ~120 and ~140 (no read vs. read), with the change it's now ~970 and ~1300.
Smaller payload tests improved by ~10%-33%.

@BrennanConroy BrennanConroy added Perf area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions labels Nov 1, 2023
@BrennanConroy BrennanConroy merged commit 0fe51bd into main Nov 2, 2023
@BrennanConroy BrennanConroy deleted the brecon/multipart2 branch November 2, 2023 19:34
@ghost ghost added this to the 9.0-preview1 milestone Nov 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions Perf

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Explore switching MultipartReaderStream to use IndexOf

3 participants