Skip to content

Commit 4c98272

Browse files
committed
calculate digest in batches
This is intended to increase performance
1 parent 8957955 commit 4c98272

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

include/boost/json/detail/digest.hpp

+34-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
#ifndef BOOST_JSON_DETAIL_DIGEST_HPP
1111
#define BOOST_JSON_DETAIL_DIGEST_HPP
1212

13+
#include <algorithm>
14+
#include <array>
15+
#include <cstring>
16+
1317
namespace boost {
1418
namespace json {
1519
namespace detail {
@@ -23,15 +27,39 @@ digest(
2327
std::size_t salt) noexcept
2428
{
2529
#if BOOST_JSON_ARCH == 64
26-
std::uint64_t const prime = 0x100000001B3ULL;
27-
std::uint64_t hash = 0xcbf29ce484222325ULL;
30+
using hash_t = std::uint64_t;
31+
hash_t const prime = 0x100000001B3ULL;
32+
hash_t hash = 0xcbf29ce484222325ULL;
2833
#else
29-
std::uint32_t const prime = 0x01000193UL;
30-
std::uint32_t hash = 0x811C9DC5UL;
34+
using hash_t = std::uint32_t;
35+
hash_t const prime = 0x01000193UL;
36+
hash_t hash = 0x811C9DC5UL;
3137
#endif
3238
hash += salt;
33-
for(; b != e; ++b)
34-
hash = (*b ^ hash) * prime;
39+
40+
constexpr std::size_t step = sizeof(hash_t);
41+
std::size_t n = std::distance(b, e);
42+
std::size_t const m = n % step;
43+
44+
char temp[step];
45+
hash_t batch;
46+
while( n > m )
47+
{
48+
std::copy_n(b, step, temp);
49+
50+
std::memcpy(&batch, temp, step);
51+
hash = (batch ^ hash) * prime;
52+
53+
std::advance(b, step);
54+
n -= step;
55+
}
56+
57+
std::memset(temp, 0, step);
58+
std::copy_n(b, n, temp);
59+
60+
std::memcpy(&batch, temp, step);
61+
hash = (batch ^ hash) * prime;
62+
3563
return hash;
3664
}
3765

0 commit comments

Comments
 (0)