Skip to content

[http] Headermap Lazy map addition#12656

Merged
mattklein123 merged 30 commits intoenvoyproxy:masterfrom
adisuissa:header_map_lazy_map
Sep 30, 2020
Merged

[http] Headermap Lazy map addition#12656
mattklein123 merged 30 commits intoenvoyproxy:masterfrom
adisuissa:header_map_lazy_map

Conversation

@adisuissa
Copy link
Copy Markdown
Contributor

Commit Message: Adding a lazy map to the current header-map implementation.

Additional Description: This is a continuation of #9261. Adding a map to headermap's HeaderList to access headers by key in O(1) instead of O(n).
In addition some benchmarks that emulate encoding and decoding of headers, and route matching by headers are added.

Risk Level: High - changes to headermap.
Testing: Added RemoveIf test, and some perf tests.
Docs Changes: Once the design is settled, I'll update the headermap doc
Release Notes: None.

Signed-off-by: Adi Suissa-Peleg adip@google.com

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
@adisuissa
Copy link
Copy Markdown
Contributor Author

adisuissa commented Aug 14, 2020

Newly added benchmarks description:

  • headerMapImplEmulateH1toH2Upgrade - emulates the encodeHeaders (H2) code, when upgrading a request from H1 to H2.
  • headerMapImplEmulateH2toH1Upgrade - emulates the decodeHeaders (H2) code, when upgrading a response from H2 to H1.
  • headerMapImplRemovePrefix - emulates removal of varying number of headers with prefix, from a header-map that also has headers without the prefix.
  • manyCountryRoutesLongHeaders - emulates the route matching code where there are 250 backends, and the routing is done using a header ("x-country"). A request with ~100 headers is dispatched, and its requested country header doesn't exist in any route. This causes the old headermap implementation to iterate over all header keys, and many comparisons of the "x-country" header.

Post-runtime configuration results:
Headermap benchmark results (average of 3 executions, more thresholds):

Benchmark name No lazy map threshold=0 threshold=1 threshold=2 threshold=3 std::mmap-T0 std::mmap-T1 std::mmap-T2 std::mmap-T3 btree-T0 btree-T1 btree-T2 btree-T3
headerMapImplCreate 13.3333 86 85.6667 87.9333 87.6667 86.4667 86.2667 86.8667 88.5333 86.5 89.6333 87.6 88.2333
headerMapImplSetReference/0 59.1 74.7333 74.6667 46.4667 46.4333 65.2 65.1 45.5333 45.1 83.5667 85.2667 46.5333 47.4333
headerMapImplSetReference/1 68.6 78.5333 77.4333 79.5 51.1 76.3333 75.7667 76.5 49.8 88.7667 89.6667 87.9667 52
headerMapImplSetReference/5 105 75.1667 76.0333 76.5 76.0667 94.2 93.2667 93.5667 94.6 99.1333 101.033 100.9 100.6
headerMapImplSetReference/10 158 74.8667 74.7 78.0667 76.1667 103.667 103 103.333 103.333 135.667 138 135.333 136.667
headerMapImplSetReference/50 355.667 76.2667 76.5333 80.0333 78.4333 122.667 121.667 122 123 132 134.667 132 133.667
headerMapImplGet/0 12.6667 20.6333 19.9667 17.2333 17.0667 17.2333 17 14.1 14.4333 22.7667 23.1 16.8667 17
headerMapImplGet/1 19.9667 21.3333 20.7 20.7333 24 20.9333 20.7 20.7667 21.4 26.8 27.3 26.8 24.4333
headerMapImplGet/5 48.6333 20.6333 19.9667 20 19.9333 32.3333 31.6333 31.4667 31.6667 30.6667 31.0333 30.6667 30.8667
headerMapImplGet/10 89.4333 20.5667 20.0333 19.9667 19.9333 39 38.3 38.6 38.9667 28.0333 28.2667 28 28.2667
headerMapImplGet/50 276.333 21.1333 20.4667 20.8 20.4 53.3 52.7 52.8667 52.7667 39.2333 39.9333 39.5333 39.7333
headerMapImplGetInline/0 5.12333 5.15333 5.11 5.15 5.14333 5.25333 5.14667 5.14333 5.15667 5.67 5.71 5.66333 5.67333
headerMapImplGetInline/1 5.12667 5.09 5.09333 5.10333 5.08667 5.21 5.09333 5.10667 5.12 5.66667 5.71 5.67333 5.68333
headerMapImplGetInline/5 5.12667 5.08667 5.08667 5.1 5.08667 5.21 5.13333 5.11 5.12 5.77667 5.71333 5.65667 5.67667
headerMapImplGetInline/10 5.12 5.09 5.09 5.09333 5.1 5.21667 5.09333 5.10667 5.12 5.66333 5.71 5.65667 5.68
headerMapImplGetInline/50 5.12667 5.09333 5.08667 5.09667 5.09667 5.22 5.11 5.10667 5.12667 5.66667 5.71333 5.66 5.68
headerMapImplSetInlineMacro/0 9.65333 9.8 9.79667 9.81 9.82667 9.80667 9.74667 9.74 10.0733 9.68667 9.77 9.66667 9.71
headerMapImplSetInlineMacro/1 9.89667 9.8 9.8 9.83 9.82667 9.80333 9.76 9.73667 10.0867 9.67333 9.92667 9.67667 9.70667
headerMapImplSetInlineMacro/5 9.64667 9.79333 9.79333 9.81667 9.82 9.79333 10.0633 9.74333 10.13 9.67667 9.67667 9.68333 9.70667
headerMapImplSetInlineMacro/10 9.64333 9.79333 9.79333 9.80667 9.81667 9.81 10.0767 9.73667 10.1 9.67 9.68667 9.68333 9.71667
headerMapImplSetInlineMacro/50 9.66667 9.8 9.79 9.82 9.82333 9.81667 9.77667 9.75333 10.1 9.67333 9.68 9.68667 9.70667
headerMapImplSetInlineInteger/0 23.9 24.3 24.3 24.3667 25.2333 23.6333 23.6667 23.5333 24.6 24.7 24.6667 24.5667 24.5667
headerMapImplSetInlineInteger/1 23.6667 24.3333 24.3333 24.8667 24.4 23.6 23.5667 23.5333 23.4333 24.6333 24.6333 24.6 24.5667
headerMapImplSetInlineInteger/5 23.6667 24.3333 24.3 24.4333 24.3667 23.8 23.5333 23.5 23.5 24.7 24.6333 24.6 24.7333
headerMapImplSetInlineInteger/10 23.7 24.3333 24.3667 24.4 24.4 24.4333 23.5667 23.5 23.4 24.9 24.7333 24.5667 24.5667
headerMapImplSetInlineInteger/50 23.6333 24.3667 24.3667 24.4 24.4 23.6333 23.5333 24.1333 23.8667 24.7667 24.6667 24.5333 24.9333
headerMapImplGetByteSize/0 1.57333 1.71333 1.70667 1.73667 1.71333 1.57667 1.58667 1.57 1.57333 1.24667 1.23667 1.33667 1.33667
headerMapImplGetByteSize/1 1.56667 1.69333 1.72 1.73 1.71333 1.57333 1.56333 1.57667 1.56667 1.24667 1.23667 1.33333 1.33667
headerMapImplGetByteSize/5 1.56667 1.70667 1.71 1.71333 1.71667 1.55333 1.56667 1.58 1.56333 1.24667 1.24 1.33667 1.33333
headerMapImplGetByteSize/10 1.55 1.73333 1.69667 1.72667 1.71 1.56667 1.57667 1.57667 1.57 1.24667 1.24 1.33667 1.33667
headerMapImplGetByteSize/50 1.56 1.70667 1.69 1.71667 1.71 1.53667 1.57 1.57667 1.55333 1.24333 1.24 1.33 1.33667
headerMapImplIterate/0 6.76333 6.67 6.66667 6.66333 6.67333 6.74667 6.7 6.68667 6.69 6.54667 6.50667 6.5 6.62333
headerMapImplIterate/1 7.52 8.04667 8.05333 8.08667 8.05333 8.11 8.06 8.03667 8.05333 8.08 8.02333 8.02333 8.12667
headerMapImplIterate/5 13.5 14 14 14 14 14.0667 13.9667 13.9333 13.9 13.9667 13.8 13.8333 14
headerMapImplIterate/10 20.3 21.0667 21.0667 21.0667 21 21.1667 21.0333 20.9333 21 21.1 20.9 20.8667 21.3333
headerMapImplIterate/50 83.7667 82.8667 82.4 82.3333 82.2 84.8 83.7333 83.5333 83.7333 85.9667 85.1667 85.3667 86.4333
headerMapImplRemove/0 59.4 74.7667 74.4 46.0667 46 66.3 66.6333 44 43.9 83.4333 82.7333 48.1333 48.7333
headerMapImplRemove/1 69.6333 78.1667 76.3333 77.8 50.7333 77.5333 76.6 77.0667 49.6 88.3333 87.3667 87.4333 53.9667
headerMapImplRemove/5 106.333 74.9667 74 75.6333 74.3667 94.6 94.3 94.0333 93.8333 99.4333 98.4333 98.4333 99.8667
headerMapImplRemove/10 158 74.6 74 75.8667 74.4667 103.667 103.333 103.333 103.667 136.667 135.333 135.333 136.667
headerMapImplRemove/50 354.667 76.0667 76.1 78 76.5667 122.333 121.333 122 121.333 132.333 131 131 132.333
headerMapImplRemoveInline/0 63.7667 78.9 73.7667 73.9 73.8667 72.5333 72.5333 71.4333 72.9 71.2667 71.7 70.1667 71.3667
headerMapImplRemoveInline/1 68.5333 78.7 73.9 73.9 73.9 72.4 72.5 71.2 73.2667 70.7 71.9333 69.7667 71.0333
headerMapImplRemoveInline/5 63.7 78.7333 73.7333 73.8333 73.7667 72.4 72.2333 72 72.8 71.9667 70.7667 69.9 71.1333
headerMapImplRemoveInline/10 63.6333 78.8 73.7 74.1333 73.7667 72.3 72.1333 71.3 72.7 70.7667 70.8 70.4333 71.0333
headerMapImplRemoveInline/50 64 78.9333 73.9333 73.8 73.8667 72.7 72.2 71.3333 72.8667 70.9 70.7333 69.7667 71.0333
headerMapImplPopulate 345.667 437.333 432 435.333 438.667 435.333 426 436.667 437.333 444.667 439.333 440.333 448.333
headerMapImplEmulateH1toH2Upgrade/0 258.333 377 378 377.667 374 367.333 357.667 364.333 364.333 365 367.667 365.333 374
headerMapImplEmulateH1toH2Upgrade/1 322.333 441 441.667 440.667 438 429.667 423 426.667 428 427.667 431.667 429.333 438.667
headerMapImplEmulateH1toH2Upgrade/5 558.333 702 699.333 699 699.333 683.667 674.667 678.333 679.667 688.667 688 691.333 699.333
headerMapImplEmulateH1toH2Upgrade/10 861.333 1009.67 1003.67 1006 1007.33 984.667 976 979 977.667 993.333 990.333 987.667 1001.33
headerMapImplEmulateH1toH2Upgrade/50 3234.67 3410.67 3391.33 3407.67 3401.67 3410.33 3391.33 3373.33 3371 3390.33 3369.33 3353.67 3435
headerMapImplEmulateH2toH1Upgrade/0 80.6667 83.2333 83.2333 84.2333 83.2333 86.6667 87.2667 86.1 86.2 86.8333 86.4 86.2667 87.1667
headerMapImplEmulateH2toH1Upgrade/1 86.8 89.8333 89.6333 89.8333 89.9 92.9 93.6333 92.0333 92.4 93.0667 92.6667 92.7667 93.1333
headerMapImplEmulateH2toH1Upgrade/5 113.333 115.333 115 115 115.333 120.333 124.667 119.333 119.333 118.667 117.667 117.667 119.333
headerMapImplEmulateH2toH1Upgrade/10 154 152.667 152.667 154 154.333 162.333 166.667 160 160 157.667 156.667 156 157.667
headerMapImplEmulateH2toH1Upgrade/50 417.667 411 410.333 409 409.333 442.333 434.333 434 434.667 420.667 419 416.333 420

The manyCountryRoutesLongHeaders benchmark results:
Original headermap: 106606 ns
Lazymap-absl::flat_hash_map (threshold=0): 11615 ns
Lazymap-std::multimap (threshold=0): 25801 ns
Lazymap-absl::btree (threshold=0): 16017 ns

Pre-runtime configuration results:
Headermap benchmark results (average of 3 executions, more thresholds):

Benchmark name No lazy map threshold=0 threshold=1 threshold=2 threshold=3 std::map-T0 std::map-T1 std::map-T2 std::map-T3 std::mmap-T0 std::mmap-T1 std::mmap-T2 std::mmap-T3 btree-T0 btree-T1 btree-T2 btree-T3
headerMapImplCreate 13.3333 16.0333 15.3667 15.3 15.9667 13.8667 13.8667 14.5667 16.3 14 13.7333 13.8 14.9 16.2333 16.8333 18.9333 16.2333
headerMapImplSetReference/0 59.1 73.7667 78.0333 45.6667 45.9333 69.7667 68.9333 47.1667 45.7667 67.5333 66.0333 44.8667 45.2667 78.7 83.2333 46.0333 45.9667
headerMapImplSetReference/1 68.6 74.2 80.0667 74.0667 50.4333 79.6 81.5333 80.6667 50 77.6333 75.4 75.3333 50.2333 84.5333 87.4667 87.8667 50.2667
headerMapImplSetReference/5 105 73.6 77.8333 74.0333 75.5667 107 107.667 107.667 107 93.7667 95.3333 94.7 94.9 96.7667 98.1333 97.8 97.9333
headerMapImplSetReference/10 158 73.4 86.4333 79.8 82.5 119 120.333 120 120 103 106 105.333 105 133.667 135.333 135.333 136.333
headerMapImplSetReference/50 355.667 73.5667 87 87.2 80.6667 145.333 146.667 147 147 121.333 126 125 125 130 132.333 132 133.333
headerMapImplGet/0 12.6667 19.0667 19.6333 14.2667 14.1333 16.1333 16.6333 14.0333 14.2 15.3 14.6667 12.9667 13.0333 19.4667 19.4 14.5667 14.5667
headerMapImplGet/1 19.9667 19.0667 19.6333 19.6667 20.6667 21.4333 21.2667 21.1 21.5667 20.3 18.4667 18.1 19.7667 23.1667 22.8667 23.2667 22.6667
headerMapImplGet/5 48.6333 19.0667 19.6333 19.6667 19.6667 34.9 35.0333 34.8667 34.9667 33.7667 31.6333 31.3333 31.7667 26.8 26.2 26.5667 26.6
headerMapImplGet/10 89.4333 19.1 20.9667 19.6667 21.5 41.8667 42.2 42.3 42.2 40.4 38.5333 38.5333 39 25.0333 23.8333 24.6667 24.3
headerMapImplGet/50 276.333 19.0667 22.3 23.5667 21.6 56.3667 56.8333 56.6 56.6333 55 53.5 53.5 53.8 35.0333 33.8333 33.4 33.3333
headerMapImplGetInline/0 5.12333 5.1 5.30667 5.10667 5.11 5.08667 5.35333 5.28333 5.34 5.08333 5.12667 5.07667 5.78 5.28333 5.26 5.33 5.68333
headerMapImplGetInline/1 5.12667 5.06667 5.11 5.10667 5.11 5.08667 5.2 5.28333 5.34667 5.28333 5.13 5.07 5.57333 5.28333 5.26333 5.31333 5.68333
headerMapImplGetInline/5 5.12667 5.08 5.11333 5.11 5.11667 5.08 5.19333 5.27667 5.35 5.08 5.13333 5.07333 5.57 5.49667 5.26333 5.30333 5.68667
headerMapImplGetInline/10 5.12 5.07333 5.10333 5.11667 5.10667 5.08333 5.19333 5.28 5.35333 5.08667 5.13 5.07667 5.57333 5.27667 5.26667 5.30333 5.68333
headerMapImplGetInline/50 5.12667 5.06 5.30333 5.10333 5.10667 5.08667 5.19 5.28667 5.36 5.07667 5.12667 5.07333 5.57 5.28333 5.26333 5.30333 5.68667
headerMapImplSetInlineMacro/0 9.65333 9.70667 10.0633 9.69 9.67667 9.36 9.38 9.97 9.43667 9.19333 9.66333 9.08333 9.79333 9.83667 10.1567 9.70667 10.3
headerMapImplSetInlineMacro/1 9.89667 9.71333 9.68667 9.7 9.68333 9.36667 9.37667 9.97667 9.49667 9.19667 10.4333 9.11 9.79 9.77 10.1167 9.7 10.2567
headerMapImplSetInlineMacro/5 9.64667 9.71 9.68667 9.68333 9.67667 9.37333 9.38667 9.91333 9.43 9.19333 9.69667 9.1 9.79333 9.82 10.15 9.68333 10.29
headerMapImplSetInlineMacro/10 9.64333 9.70667 9.68667 9.70667 9.68 9.37667 9.37667 9.91667 9.43333 9.18667 9.66333 9.08 9.80333 9.75 10.12 9.69667 10.26
headerMapImplSetInlineMacro/50 9.66667 9.71667 9.69333 9.68667 9.69333 9.36667 9.38 9.90667 9.42667 9.19 9.65333 9.09 9.79333 9.73667 10.1367 9.69 10.2633
headerMapImplSetInlineInteger/0 23.9 23.8 25.1 23.8 23.7667 23.8 24 23.8 24.1333 23.8 23.8333 23.7333 24.1667 24.2667 24.6667 24.5 24.3333
headerMapImplSetInlineInteger/1 23.6667 23.8 23.9333 23.7667 23.7667 23.8 24 23.8333 24.1333 23.8 23.8333 23.8 23.7667 24.2333 24.6 24.5 24.3333
headerMapImplSetInlineInteger/5 23.6667 23.8 24.0667 23.7667 23.7667 24.0667 24.0333 23.8333 24.1333 23.8333 23.8 23.7667 23.7667 24.2667 24.4 24.5 24.3667
headerMapImplSetInlineInteger/10 23.7 23.8333 23.7667 23.8667 23.8667 23.8333 23.9667 23.8667 24.1667 23.8 23.8333 23.7667 23.8333 24.3 25.2667 24.5 24.3333
headerMapImplSetInlineInteger/50 23.6333 23.9 23.8333 23.7333 23.9 23.8333 24.1 23.9 24.1333 24.1667 23.8 23.8 23.7667 24.2667 24.5667 24.5 24.3667
headerMapImplGetByteSize/0 1.57333 1.62333 1.70333 1.62667 1.63 1.69 1.66667 1.62 1.65 1.57667 1.56333 1.57 1.59333 1.25 1.24333 1.23667 1.23333
headerMapImplGetByteSize/1 1.56667 1.62 1.70333 1.61667 1.63 1.68667 1.66333 1.60667 1.64 1.56333 1.56667 1.56333 1.58333 1.25 1.23667 1.24 1.24
headerMapImplGetByteSize/5 1.56667 1.61 1.70333 1.64333 1.62667 1.70333 1.67333 1.60667 1.64333 1.55333 1.57667 1.59333 1.59 1.25 1.24 1.25333 1.23667
headerMapImplGetByteSize/10 1.55 1.61667 1.70667 1.63333 1.62667 1.69333 1.67667 1.62667 1.60667 1.55 1.59 1.57667 1.56 1.25 1.24 1.23333 1.23667
headerMapImplGetByteSize/50 1.56 1.64333 1.67667 1.60333 1.62667 1.7 1.66333 1.63667 1.63667 1.57333 1.59 1.58 1.59 1.25 1.24 1.24 1.23333
headerMapImplIterate/0 6.76333 6.22333 6.16667 6.21333 6.20333 6.31333 6.43667 6.44667 6.42667 6.23333 6.35 6.30667 6.30333 6.54667 6.36667 6.32 6.32333
headerMapImplIterate/1 7.52 7.40667 7.41 7.45667 7.45333 7.45 7.42 7.43 7.42667 7.34 7.46333 7.41333 7.40667 8.08 8.13667 8.08 8.08
headerMapImplIterate/5 13.5 13.3 13.1 13.2333 13.2333 13.2667 13.4 13.4 13.6333 13.2 13.4 13.2333 13.4667 13.7 14 13.6667 13.9667
headerMapImplIterate/10 20.3 20.0333 19.5 19.4333 19.4 20 20.2 20.2 20.8667 19.7 19.4 19.4333 20.4333 20.6667 20.4 20.3667 20.2667
headerMapImplIterate/50 83.7667 81.6 79.2333 79.7333 78.8333 79.8333 82.0667 82.3333 85.1333 80.2333 79.3333 79.6 84.4333 87.3333 82.3333 81.8333 81.8333
headerMapImplRemove/0 59.4 72.4667 76.1333 45.4 45.6333 69.9667 68.0333 46.1667 46.2333 65.6667 66.0667 43.9333 44.4 78.3333 81.9333 46.3333 45.9333
headerMapImplRemove/1 69.6333 73.5333 77.9 76 50.1333 79.3333 80.1667 79.9333 50.9667 76.7333 75.2 74.9 49.6667 83.7 86.6333 85.5667 51.1
headerMapImplRemove/5 106.333 72.5333 76.6667 75.0333 76.9 105.667 106.667 106.333 106.667 92.3 95.7667 95.3667 95.2 95.1667 97.3667 96.1333 96.2
headerMapImplRemove/10 158 72.4667 84.3667 81.4667 84 118 119.333 119 118.667 101.333 105.667 105.667 105 133.333 136.333 134.333 134.333
headerMapImplRemove/50 354.667 73.2667 85.1 86.2667 82.0333 144.667 145.667 146.667 146 120.667 125 124.667 125 129.333 131.667 130.667 130
headerMapImplRemoveInline/0 63.7667 77.4333 74.5 76.0667 76.1 67.6667 70.3333 69.1667 69.9667 70.9 71 72.1667 73.9333 74.1667 69.5 69.3667 69.9333
headerMapImplRemoveInline/1 68.5333 77.3667 74.5333 75.9667 76.2 68.0333 70.5 69.3 70.5333 70.9667 73.0667 73.4 77.6667 73.9667 69.2667 69.2667 69.7
headerMapImplRemoveInline/5 63.7 77.9 73.6 74.8333 76.9 67.7333 70.1 70.1667 70.0333 70.9 70.7333 72.1667 73.5667 75.3 69.5667 69.2667 69.5
headerMapImplRemoveInline/10 63.6333 77.3333 75.9 77.7 77.2667 67.8 70.2667 69.4 70.0333 71.2333 71.8667 72.9 74.1 74.1333 69.8 69.6667 69.7
headerMapImplRemoveInline/50 64 77.1667 75 76.6667 76.6333 68.1333 72 70.7 73.9667 71.4667 70.8667 72.1667 74.1 74.2333 70.0333 69.6 69.9333
headerMapImplPopulate 345.667 347.667 353.667 348 348.333 345.667 350.333 358 350 354.667 351 345 346.667 348.333 357 356.667 356.667
headerMapImplEmulateH1toH2Upgrade/0 258.333 294 289.333 290.333 290.333 269.333 274 276.667 280 272 279.333 274 272 278 278 274.667 272
headerMapImplEmulateH1toH2Upgrade/1 322.333 372 350.667 351 351.333 328.667 336 338.333 335.667 329.667 339.333 340.667 331 339.667 339 337 333.667
headerMapImplEmulateH1toH2Upgrade/5 558.333 608 589.667 589.667 588.333 565.333 569.667 575.667 571 566.333 572.667 582.333 578 582.667 592 591 579.667
headerMapImplEmulateH1toH2Upgrade/10 861.333 897 881.333 885.667 884 854 855 863.333 858.667 851.667 864.667 867 855 877.333 886.667 877 864.667
headerMapImplEmulateH1toH2Upgrade/50 3234.67 3261 3226.67 3234.67 3236.33 3187.33 3180 3223.33 3198.33 3187.67 3194 3212.33 3201.67 3255.67 3253.67 3238.67 3253
headerMapImplEmulateH2toH1Upgrade/0 80.6667 83.3667 80.3333 80.7 80.2667 82.3333 82.3667 83.3 83.0333 82.4 82.9 83.3667 83.7 83.6 84.2 83.6 83.7
headerMapImplEmulateH2toH1Upgrade/1 86.8 90.3667 85.8333 86.7667 85.9333 88.7 88.8667 88.8667 89.2333 88.7667 89.1 89.7 89.8667 89.6 90.7667 90.2667 89.9667
headerMapImplEmulateH2toH1Upgrade/5 113.333 117.333 109 110.333 110.333 113 115 115.333 115 112.667 113 115 113.667 114 120.333 118 120.667
headerMapImplEmulateH2toH1Upgrade/10 154 158.333 145 147.333 148 150 153.667 153.667 153.667 150 150 151.333 151.667 152 162.333 160 159.333
headerMapImplEmulateH2toH1Upgrade/50 417.667 434 375 387 390 381.333 409 412.667 410.333 395 397 394.333 397.667 398.333 445.333 440.333 439.667

The manyCountryRoutesLongHeaders benchmark results:
Original headermap: 106606 ns
Lazymap-absl::flat_hash_map (threshold=0): 11424 ns
Lazymap-std::map (threshold=0): 26044 ns
Lazymap-std::multimap (threshold=0): 26759 ns
Lazymap-absl::btree (threshold=0): 15945 ns

Summary:

  • Closer look at the microbenchmarks suggests that the threshold should be set to 2-3, and then the map should be used.
  • In some microbenchmarks std::map is a bit faster than absl::flat_hash_map, while in others it is slower. For thresholds 2-3 it seems that absl::flat_hash_map is faster than std::map.
  • The benchmarks emulating encodeHeaders and decodeHeaders suggests some penalty on the encoding emulation compared with the original headermap implementation. There isn't a clear winner between std::map and absl::flat_hash_map, but they seem to be almost on par (except maybe for the headerMapImplEmulateH2toH1Upgrade/50 test).
  • The route matching benchmark shows ~10x improvement in this case when using absl::flat_hash_map. std::map is about 2.5x slower than absl::flat_hash_map.
  • Using std::multimap or absl::btree_multimap mostly doesn't seem to improve the performance over absl::flat_hash_map. (Note that with std::multimap the removePrefix can be implemented more efficiently, and will have better performance in some instances).
  • The current runtime configuration that executes per-headermap instance runtime call has a non-negligible performance penalty. This should be addressed in a future PR.

@adisuissa
Copy link
Copy Markdown
Contributor Author

@mattklein123 @jmarantz @antoniovicente, please take a look.
This is mainly following @jmarantz earlier design.
I've added some tests to try to emulate possible scenarios.

@mattklein123 mattklein123 self-assigned this Aug 14, 2020
Copy link
Copy Markdown
Contributor

@jmarantz jmarantz left a comment

Choose a reason for hiding this comment

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

flushing some comments; haven't looked at speed test yet

@jmarantz
Copy link
Copy Markdown
Contributor

your country-code test is a good one. What do we get when we use a std::map for that?

@jmarantz jmarantz self-assigned this Aug 15, 2020
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
@adisuissa
Copy link
Copy Markdown
Contributor Author

adisuissa commented Aug 17, 2020

your country-code test is a good one. What do we get when we use a std::map for that?

That was @antoniovicente's idea (and I agree it is a good test). Compared to absl::flat_hash_map, std::map is 2.5x slower. I've also updated the comparison comment with this data.

@jmarantz Please let me know if you have any other ideas/questions.

@adisuissa
Copy link
Copy Markdown
Contributor Author

Memory consumption: The original implementation (and the lazy map too) reserves memory for the custom headers in each request/response. Here is a breakdown of the memory usage (no custom defined headers other than the default ones):

  • RequestHeaderMap:
    • static allocation: 1,010KiB for the Trie.
    • per-request: 460 bytes.
  • ResponseHeaderMap:
    • static allocation: 546KiB for the Trie.
    • per-response: 258 bytes.

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
@stale
Copy link
Copy Markdown

stale bot commented Aug 29, 2020

This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@stale stale bot added the stale stalebot believes this issue/PR has not been touched recently label Aug 29, 2020
Copy link
Copy Markdown
Contributor

@jmarantz jmarantz left a comment

Choose a reason for hiding this comment

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

It'd be great to get this in. What's the next step?

@stale stale bot removed the stale stalebot believes this issue/PR has not been touched recently label Sep 1, 2020
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
…the benchmarks

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
@adisuissa
Copy link
Copy Markdown
Contributor Author

It'd be great to get this in. What's the next step?

Sorry, forgot to update this PR.
Summary so far:
Updated the lazy-map to use a runtime feature ("envoy.http.headermap.lazy_map_min_size"), and tried to introduce new removePrefix tests (couldn't find the tests you mentioned in previous non-merged PRs).
I haven't seen differences in these tests too, and realized that I need to reimplement removePrefix when using a BTree. Should be done by tomorrow.

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Thanks this is great work. Just a few small comments. Very excited to see this land.

/wait

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
@mattklein123
Copy link
Copy Markdown
Member

Thanks LGTM. Going to to mark this exempt from stale bot until we land this.

@mattklein123 mattklein123 added no stalebot Disables stalebot from closing an issue waiting:any labels Sep 8, 2020
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
@mattklein123 mattklein123 removed the no stalebot Disables stalebot from closing an issue label Sep 29, 2020
@mattklein123
Copy link
Copy Markdown
Member

Thanks for your patience. Can you merge main and then we can do a final pass on this and merge?

/wait

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
@adisuissa
Copy link
Copy Markdown
Contributor Author

@mattklein123 latest main is now merged, PTAL.

@adisuissa
Copy link
Copy Markdown
Contributor Author

/retest
(failed accessing homebrew's site)

@repokitteh-read-only
Copy link
Copy Markdown

Retrying Azure Pipelines, to retry CircleCI checks, use /retest-circle.
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #12656 (comment) was created by @adisuissa.

see: more, trace.

Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Thanks, fantastic work. Just 2 small comments. Thank you! @jmarantz any further comments?

/wait

Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Signed-off-by: Adi Suissa-Peleg <adip@google.com>
Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Nice!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants