From 4c9827278720205f921928bb37fd57edde49d46b Mon Sep 17 00:00:00 2001 From: Dmitry Arkhipov Date: Sun, 8 Aug 2021 07:19:41 +0300 Subject: [PATCH 1/3] calculate digest in batches This is intended to increase performance --- include/boost/json/detail/digest.hpp | 40 +++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/include/boost/json/detail/digest.hpp b/include/boost/json/detail/digest.hpp index 2d9465c00..49a823b32 100644 --- a/include/boost/json/detail/digest.hpp +++ b/include/boost/json/detail/digest.hpp @@ -10,6 +10,10 @@ #ifndef BOOST_JSON_DETAIL_DIGEST_HPP #define BOOST_JSON_DETAIL_DIGEST_HPP +#include +#include +#include + namespace boost { namespace json { namespace detail { @@ -23,15 +27,39 @@ digest( std::size_t salt) noexcept { #if BOOST_JSON_ARCH == 64 - std::uint64_t const prime = 0x100000001B3ULL; - std::uint64_t hash = 0xcbf29ce484222325ULL; + using hash_t = std::uint64_t; + hash_t const prime = 0x100000001B3ULL; + hash_t hash = 0xcbf29ce484222325ULL; #else - std::uint32_t const prime = 0x01000193UL; - std::uint32_t hash = 0x811C9DC5UL; + using hash_t = std::uint32_t; + hash_t const prime = 0x01000193UL; + hash_t hash = 0x811C9DC5UL; #endif hash += salt; - for(; b != e; ++b) - hash = (*b ^ hash) * prime; + + constexpr std::size_t step = sizeof(hash_t); + std::size_t n = std::distance(b, e); + std::size_t const m = n % step; + + char temp[step]; + hash_t batch; + while( n > m ) + { + std::copy_n(b, step, temp); + + std::memcpy(&batch, temp, step); + hash = (batch ^ hash) * prime; + + std::advance(b, step); + n -= step; + } + + std::memset(temp, 0, step); + std::copy_n(b, n, temp); + + std::memcpy(&batch, temp, step); + hash = (batch ^ hash) * prime; + return hash; } From 699a2e4d5eea7b611cd5b349e559d3fc150a7ccd Mon Sep 17 00:00:00 2001 From: Dmitry Arkhipov Date: Fri, 16 Jun 2023 17:36:29 +0300 Subject: [PATCH 2/3] temp --- include/boost/json/detail/digest.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/boost/json/detail/digest.hpp b/include/boost/json/detail/digest.hpp index 49a823b32..94d318df5 100644 --- a/include/boost/json/detail/digest.hpp +++ b/include/boost/json/detail/digest.hpp @@ -41,23 +41,23 @@ digest( std::size_t n = std::distance(b, e); std::size_t const m = n % step; - char temp[step]; + std::array temp; hash_t batch; while( n > m ) { - std::copy_n(b, step, temp); + std::copy_n(b, step, temp.data()); - std::memcpy(&batch, temp, step); + std::memcpy(&batch, temp.data(), step); hash = (batch ^ hash) * prime; std::advance(b, step); n -= step; } - std::memset(temp, 0, step); - std::copy_n(b, n, temp); + temp.fill(0); + std::copy_n(b, n, temp.data()); - std::memcpy(&batch, temp, step); + std::memcpy(&batch, temp.data(), step); hash = (batch ^ hash) * prime; return hash; From c2915984ce1fd30284c6912edb3963ec76b638e8 Mon Sep 17 00:00:00 2001 From: Dmitry Arkhipov Date: Mon, 19 Jun 2023 18:30:35 +0300 Subject: [PATCH 3/3] temp2 --- include/boost/json/detail/digest.hpp | 40 ++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/include/boost/json/detail/digest.hpp b/include/boost/json/detail/digest.hpp index 94d318df5..3fb8a70d7 100644 --- a/include/boost/json/detail/digest.hpp +++ b/include/boost/json/detail/digest.hpp @@ -39,11 +39,10 @@ digest( constexpr std::size_t step = sizeof(hash_t); std::size_t n = std::distance(b, e); - std::size_t const m = n % step; std::array temp; hash_t batch; - while( n > m ) + while( n >= step ) { std::copy_n(b, step, temp.data()); @@ -63,6 +62,43 @@ digest( return hash; } +// Calculate salted digest of string +template<> +inline +std::size_t +digest( + char const* b, + char const* e, + std::size_t salt) noexcept +{ +#if BOOST_JSON_ARCH == 64 + using hash_t = std::uint64_t; + hash_t const prime = 0x100000001B3ULL; + hash_t hash = 0xcbf29ce484222325ULL; +#else + using hash_t = std::uint32_t; + hash_t const prime = 0x01000193UL; + hash_t hash = 0x811C9DC5UL; +#endif + hash += salt; + + constexpr std::size_t step = sizeof(hash_t); + + hash_t batch; + for( ; (e - b) >= static_cast(step); b += step ) + { + std::memcpy(&batch, b, step); + hash = (batch ^ hash) * prime; + } + + batch = 0; + std::memcpy(&batch, b, e - b); + hash = (batch ^ hash) * prime; + + return hash; +} + + } // detail } // namespace json } // namespace boost