123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- //
- // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // Official repository: https://github.com/boostorg/beast
- //
- #include <boost/beast/websocket/detail/utf8_checker.hpp>
- #include <boost/beast/_experimental/unit_test/suite.hpp>
- #include <chrono>
- #include <random>
- #ifndef BEAST_USE_BOOST_LOCALE_BENCHMARK
- #define BEAST_USE_BOOST_LOCALE_BENCHMARK 0
- #endif
- #if BEAST_USE_BOOST_LOCALE_BENCHMARK
- #include <boost/locale.hpp>
- #endif
- namespace boost {
- namespace beast {
- class utf8_checker_test : public beast::unit_test::suite
- {
- std::mt19937 rng_;
- public:
- using size_type = std::uint64_t;
- class timer
- {
- public:
- using clock_type =
- std::chrono::system_clock;
- private:
- clock_type::time_point when_;
- public:
- using duration =
- clock_type::duration;
- timer()
- : when_(clock_type::now())
- {
- }
- duration
- elapsed() const
- {
- return clock_type::now() - when_;
- }
- };
- template<class UInt = std::size_t>
- UInt
- rand(std::size_t n)
- {
- return static_cast<UInt>(
- std::uniform_int_distribution<
- std::size_t>{0, n-1}(rng_));
- }
- static
- inline
- size_type
- throughput(std::chrono::duration<
- double> const& elapsed, size_type items)
- {
- using namespace std::chrono;
- return static_cast<size_type>(
- 1 / (elapsed/items).count());
- }
- std::string
- corpus(std::size_t n)
- {
- std::string s;
- s.reserve(n);
- while(n--)
- s.push_back(static_cast<char>(
- ' ' + rand(95)));
- return s;
- }
- void
- checkBeast(std::string const& s)
- {
- beast::websocket::detail::check_utf8(
- s.data(), s.size());
- }
- #if BEAST_USE_BOOST_LOCALE_BENCHMARK
- void
- checkLocale(std::string const& s)
- {
- using namespace boost::locale;
- auto p = s.begin();
- auto const e = s.end();
- while(p != e)
- {
- auto cp = utf::utf_traits<char>::decode(p, e);
- if(cp == utf::illegal)
- break;
- }
- }
- #endif
- template<class F>
- typename timer::clock_type::duration
- test(F const& f)
- {
- timer t;
- f();
- return t.elapsed();
- }
- void
- run() override
- {
- auto const s = corpus(32 * 1024 * 1024);
- for(int i = 0; i < 5; ++ i)
- {
- auto const elapsed = test([&]{
- checkBeast(s);
- checkBeast(s);
- checkBeast(s);
- checkBeast(s);
- checkBeast(s);
- });
- log << "beast: " << throughput(elapsed, s.size()) << " char/s" << std::endl;
- }
- #if BEAST_USE_BOOST_LOCALE_BENCHMARK
- for(int i = 0; i < 5; ++ i)
- {
- auto const elapsed = test([&]{
- checkLocale(s);
- checkLocale(s);
- checkLocale(s);
- checkLocale(s);
- checkLocale(s);
- });
- log << "locale: " << throughput(elapsed, s.size()) << " char/s" << std::endl;
- }
- #endif
- pass();
- }
- };
- BEAST_DEFINE_TESTSUITE(beast,benchmarks,utf8_checker);
- } // beast
- } // boost
|