diff options
| author | AlexSm <[email protected]> | 2024-01-09 18:56:40 +0100 | 
|---|---|---|
| committer | GitHub <[email protected]> | 2024-01-09 18:56:40 +0100 | 
| commit | e95f266d2a3e48e62015220588a4fd73d5d5a5cb (patch) | |
| tree | a8a784b6931fe52ad5f511cfef85af14e5f63991 /library/cpp | |
| parent | 50a65e3b48a82d5b51f272664da389f2e0b0c99a (diff) | |
Library import 6 (#888)
Diffstat (limited to 'library/cpp')
| -rw-r--r-- | library/cpp/http/io/benchmark/main.cpp | 81 | ||||
| -rw-r--r-- | library/cpp/http/io/benchmark/ya.make | 11 | ||||
| -rw-r--r-- | library/cpp/http/io/headers.cpp | 14 | ||||
| -rw-r--r-- | library/cpp/http/io/ya.make | 6 | ||||
| -rw-r--r-- | library/cpp/yt/string/unittests/enum_ut.cpp | 9 | 
5 files changed, 117 insertions, 4 deletions
diff --git a/library/cpp/http/io/benchmark/main.cpp b/library/cpp/http/io/benchmark/main.cpp new file mode 100644 index 00000000000..2a3a07b3bbf --- /dev/null +++ b/library/cpp/http/io/benchmark/main.cpp @@ -0,0 +1,81 @@ +#include <library/cpp/http/io/headers.h> + +#include <benchmark/benchmark.h> + +#include <util/stream/str.h> + +void FindHeaderFirstMatch(benchmark::State& state) { +    THttpHeaders headers; +    headers.AddHeader("Host", "example.com"); +    Y_ENSURE(headers.FindHeader("Host")); +    for (auto _ : state) { +        auto header = headers.FindHeader("Host"); +        benchmark::DoNotOptimize(header); +    } +} + +void FindHeaderNoMatchSameSize(benchmark::State& state) { +    THttpHeaders headers; +    for (char c = 'a'; c <= 'z'; ++c) { +        headers.AddHeader(TString::Join(c, "aaa"), "some value"); +    } +    Y_ENSURE(!headers.FindHeader("Host")); +    for (auto _ : state) { +        auto header = headers.FindHeader("Host"); +        benchmark::DoNotOptimize(header); +    } +} + +void FindHeaderNoMatchDifferentSizesNoCommonPrefix(benchmark::State& state) { +    THttpHeaders headers; +    for (char c = 'a'; c <= 'z'; ++c) {  // same number of headers as above +        headers.AddHeader("aaaaa", "some value"); +    } +    Y_ENSURE(!headers.FindHeader("Host")); +    for (auto _ : state) { +        auto header = headers.FindHeader("Host"); +        benchmark::DoNotOptimize(header); +    } +} + +void FindHeaderNoMatchDifferentSizesCommonPrefix(benchmark::State& state) { +    THttpHeaders headers; +    for (char c = 'a'; c <= 'z'; ++c) { +        headers.AddHeader("Host2", "some value"); +    } +    Y_ENSURE(!headers.FindHeader("Host")); +    for (auto _ : state) { +        auto header = headers.FindHeader("Host"); +        benchmark::DoNotOptimize(header); +    } +} + +void FindHeaderMoreRealisticUseCase(benchmark::State& state) { +    TString requestHeaders(R"(Host: yandex.ru +User-Agent: Mozilla/5.0 ... +Accept: */* +Accept-Language: en-US,en;q=0.5 +Accept-Encoding: gzip, deflate, br +Content-Type: text/plain;charset=UTF-8 +Content-Length: 1234 +Origin: https://a.yandex-team.ru +Connection: keep-alive +Referer: https://a.yandex-team.ru/ +Sec-Fetch-Dest: empty +Sec-Fetch-Mode: no-cors +Sec-Fetch-Site: cross-site +TE: trailers)"); +    TStringInput stream(requestHeaders); +    THttpHeaders headers(&stream); +    Y_ENSURE(headers.FindHeader("Content-Type")); +    for (auto _ : state) { +        auto header = headers.FindHeader("Content-Type"); +        benchmark::DoNotOptimize(header); +    } +} + +BENCHMARK(FindHeaderFirstMatch); +BENCHMARK(FindHeaderNoMatchSameSize); +BENCHMARK(FindHeaderNoMatchDifferentSizesNoCommonPrefix); +BENCHMARK(FindHeaderNoMatchDifferentSizesCommonPrefix); +BENCHMARK(FindHeaderMoreRealisticUseCase); diff --git a/library/cpp/http/io/benchmark/ya.make b/library/cpp/http/io/benchmark/ya.make new file mode 100644 index 00000000000..6e1d252df0c --- /dev/null +++ b/library/cpp/http/io/benchmark/ya.make @@ -0,0 +1,11 @@ +G_BENCHMARK() + +PEERDIR( +    library/cpp/http/io +) + +SRCS( +    main.cpp +) + +END() diff --git a/library/cpp/http/io/headers.cpp b/library/cpp/http/io/headers.cpp index 4ec27a29e83..f2baf640218 100644 --- a/library/cpp/http/io/headers.cpp +++ b/library/cpp/http/io/headers.cpp @@ -12,6 +12,13 @@ static inline TStringBuf Trim(const char* b, const char* e) noexcept {      return StripString(TStringBuf(b, e));  } +static inline bool HeaderNameEqual(TStringBuf headerName, TStringBuf expectedName) noexcept { +    // Most headers names have distinct sizes. +    // Size comparison adds small overhead if all headers have the same size (~4% or lower with size = 4), +    // but significantly speeds up the case where sizes are different (~4.5x for expectedName.size() = 4 and headerName.size() = 5) +    return headerName.size() == expectedName.size() && AsciiCompareIgnoreCase(headerName, expectedName) == 0; +} +  THttpInputHeader::THttpInputHeader(const TStringBuf header) {      size_t pos = header.find(':'); @@ -65,7 +72,7 @@ bool THttpHeaders::HasHeader(const TStringBuf header) const {  const THttpInputHeader* THttpHeaders::FindHeader(const TStringBuf header) const {      for (const auto& hdr : Headers_) { -        if (AsciiCompareIgnoreCase(hdr.Name(), header) == 0) { +        if (HeaderNameEqual(hdr.Name(), header)) {              return &hdr;          }      } @@ -74,7 +81,7 @@ const THttpInputHeader* THttpHeaders::FindHeader(const TStringBuf header) const  void THttpHeaders::RemoveHeader(const TStringBuf header) {      for (auto h = Headers_.begin(); h != Headers_.end(); ++h) { -        if (AsciiCompareIgnoreCase(h->Name(), header) == 0) { +        if (HeaderNameEqual(h->Name(), header)) {              Headers_.erase(h);              return;          } @@ -82,8 +89,9 @@ void THttpHeaders::RemoveHeader(const TStringBuf header) {  }  void THttpHeaders::AddOrReplaceHeader(const THttpInputHeader& header) { +    TStringBuf name = header.Name();      for (auto& hdr : Headers_) { -        if (AsciiCompareIgnoreCase(hdr.Name(), header.Name()) == 0) { +        if (HeaderNameEqual(hdr.Name(), name)) {              hdr = header;              return;          } diff --git a/library/cpp/http/io/ya.make b/library/cpp/http/io/ya.make index 0390aecf55b..20e014d011d 100644 --- a/library/cpp/http/io/ya.make +++ b/library/cpp/http/io/ya.make @@ -17,7 +17,11 @@ SRCS(  END()  RECURSE( -    fuzz      list_codings +) + +RECURSE_FOR_TESTS( +    benchmark +    fuzz      ut  ) diff --git a/library/cpp/yt/string/unittests/enum_ut.cpp b/library/cpp/yt/string/unittests/enum_ut.cpp index f30aec1cabd..4059b3d2e63 100644 --- a/library/cpp/yt/string/unittests/enum_ut.cpp +++ b/library/cpp/yt/string/unittests/enum_ut.cpp @@ -71,6 +71,15 @@ TEST(TParseEnumTest, ParseEnumWithCustomDomainName)      EXPECT_EQ(std::nullopt, TryParseEnum<ECustomDomainName>("b"));  } +TEST(TParseEnumTest, ParseBitEnum) +{ +    EXPECT_EQ(ELangs::None, TryParseEnum<ELangs>("")); +    EXPECT_EQ(ELangs::Cpp, TryParseEnum<ELangs>("cpp")); +    EXPECT_EQ(ELangs::Cpp | ELangs::Rust, TryParseEnum<ELangs>("cpp|rust")); +    EXPECT_EQ(ELangs::Cpp | ELangs::Rust, TryParseEnum<ELangs>("cpp | rust")); +    EXPECT_EQ(std::nullopt, TryParseEnum<ELangs>("unk | rust")); +} +  ////////////////////////////////////////////////////////////////////////////////  } // namespace  | 
