]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/test/bench/parser/bench_parser.cpp
67cc99a0c4e2e337c2f02c5995a7b188f6bebc6e
2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // Official repository: https://github.com/boostorg/beast
10 #include "nodejs_parser.hpp"
12 #include "test/beast/http/message_fuzz.hpp"
14 #include <boost/beast/http.hpp>
15 #include <boost/beast/core/buffer_traits.hpp>
16 #include <boost/beast/core/buffers_suffix.hpp>
17 #include <boost/beast/core/buffers_to_string.hpp>
18 #include <boost/beast/core/ostream.hpp>
19 #include <boost/beast/core/flat_buffer.hpp>
20 #include <boost/beast/core/multi_buffer.hpp>
21 #include <boost/beast/_experimental/unit_test/suite.hpp>
30 class parser_test
: public beast::unit_test::suite
33 static std::size_t constexpr N
= 2000;
35 //using corpus = std::vector<multi_buffer>;
36 using corpus
= std::vector
<flat_buffer
>;
40 std::size_t size_
= 0;
43 build_corpus(std::size_t n
, std::true_type
)
48 for(std::size_t i
= 0; i
< n
; ++i
)
52 BEAST_EXPECT(v
[i
].size() > 0);
58 build_corpus(std::size_t n
, std::false_type
)
63 for(std::size_t i
= 0; i
< n
; ++i
)
67 BEAST_EXPECT(v
[i
].size() > 0);
72 template<class ConstBufferSequence
,
76 feed(ConstBufferSequence
const& buffers
,
77 basic_parser
<isRequest
>& parser
,
80 beast::buffers_suffix
<
81 ConstBufferSequence
> cb
{buffers
};
95 if(buffer_bytes(cb
) == 0)
101 template<class Parser
>
103 testParser1(std::size_t repeat
, corpus
const& v
)
106 for(auto const& b
: v
)
110 p
.write(b
.data(), ec
);
111 if(! BEAST_EXPECTS(! ec
, ec
.message()))
112 log
<< buffers_to_string(b
.data()) << std::endl
;
116 template<class Parser
>
118 testParser2(std::size_t repeat
, corpus
const& v
)
121 for(auto const& b
: v
)
124 p
.header_limit((std::numeric_limits
<std::uint32_t>::max
)());
126 feed(b
.data(), p
, ec
);
127 if(! BEAST_EXPECTS(! ec
, ec
.message()))
128 log
<< buffers_to_string(b
.data()) << std::endl
;
132 template<class Function
>
134 timedTest(std::size_t repeat
, std::string
const& name
, Function
&& f
)
136 using namespace std::chrono
;
137 using clock_type
= std::chrono::high_resolution_clock
;
138 log
<< name
<< std::endl
;
139 for(std::size_t trial
= 1; trial
<= repeat
; ++trial
)
141 auto const t0
= clock_type::now();
143 auto const elapsed
= clock_type::now() - t0
;
145 "Trial " << trial
<< ": " <<
146 duration_cast
<milliseconds
>(elapsed
).count() << " ms" << std::endl
;
150 template<bool isRequest
>
152 basic_parser
<isRequest
>
156 verb
, string_view
, string_view
,
157 int, error_code
&) override
163 int, string_view
, int,
164 error_code
&) override
170 field
, string_view
, string_view
,
171 error_code
&) override
176 on_header_impl(error_code
&) override
182 boost::optional
<std::uint64_t> const&,
183 error_code
&) override
190 error_code
&) override
196 on_chunk_header_impl(
199 error_code
&) override
207 error_code
&) override
213 on_finish_impl(error_code
&) override
218 template<bool isRequest
, class Body
, class Fields
>
219 struct bench_parser
: basic_parser
<isRequest
>
221 using mutable_buffers_type
=
225 on_request_impl(verb
, string_view
,
226 string_view
, int, error_code
&) override
231 on_response_impl(int,
232 string_view
, int, error_code
&) override
238 string_view
, string_view
, error_code
&) override
243 on_header_impl(error_code
&) override
249 boost::optional
<std::uint64_t> const&,
250 error_code
&) override
256 string_view s
, error_code
&) override
262 on_chunk_header_impl(std::uint64_t,
263 string_view
, error_code
&) override
268 on_chunk_body_impl(std::uint64_t,
269 string_view s
, error_code
&) override
275 on_finish_impl(error_code
&) override
283 static std::size_t constexpr Trials
= 5;
284 static std::size_t constexpr Repeat
= 500;
286 creq_
= build_corpus(N
/2, std::true_type
{});
287 cres_
= build_corpus(N
/2, std::false_type
{});
289 log
<< "sizeof(request parser) == " <<
290 sizeof(null_parser
<true>) << '\n';
292 log
<< "sizeof(response parser) == " <<
293 sizeof(null_parser
<false>)<< '\n';
295 testcase
<< "Parser speed test, " <<
296 ((Repeat
* size_
+ 512) / 1024) << "KB in " <<
297 (Repeat
* (creq_
.size() + cres_
.size())) << " messages";
300 timedTest(Trials
, "http::parser",
303 testParser2
<request_parser
<dynamic_body
>>(Repeat
, creq_
);
304 testParser2
<response_parser
<dynamic_body
>>(Repeat
, cres_
);
308 timedTest(Trials
, "http::basic_parser",
311 testParser2
<bench_parser
<
312 true, dynamic_body
, fields
> >(
314 testParser2
<bench_parser
<
315 false, dynamic_body
, fields
>>(
319 timedTest(Trials
, "nodejs_parser",
322 testParser1
<nodejs_parser
<
323 true, dynamic_body
, fields
>>(
325 testParser1
<nodejs_parser
<
326 false, dynamic_body
, fields
>>(
341 BEAST_DEFINE_TESTSUITE(beast
,benchmarks
,parser
);