forked from boostorg/container_hash
Split mul31_unrolled_hash into mul31_x4_hash and mul31_x8_hash in benchmarks
This commit is contained in:
@@ -26,10 +26,8 @@
|
|||||||
|
|
||||||
// mul31_hash
|
// mul31_hash
|
||||||
|
|
||||||
class mul31_hash
|
struct mul31_hash
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
|
|
||||||
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
|
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
char const * p = st.data();
|
char const * p = st.data();
|
||||||
@@ -50,18 +48,20 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// mul31_unrolled_hash
|
// mul31_x4_hash
|
||||||
|
|
||||||
template<int Bits> struct mul31_unrolled_hash_impl;
|
struct mul31_x4_hash
|
||||||
|
|
||||||
template<> struct mul31_unrolled_hash_impl<32>
|
|
||||||
{
|
{
|
||||||
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
|
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
char const * p = st.data();
|
char const * p = st.data();
|
||||||
std::size_t n = st.size();
|
std::size_t n = st.size();
|
||||||
|
|
||||||
|
#if SIZE_MAX > UINT32_MAX
|
||||||
|
std::size_t h = 0xCBF29CE484222325ull;
|
||||||
|
#else
|
||||||
std::size_t h = 0x811C9DC5u;
|
std::size_t h = 0x811C9DC5u;
|
||||||
|
#endif
|
||||||
|
|
||||||
while( n >= 4 )
|
while( n >= 4 )
|
||||||
{
|
{
|
||||||
@@ -87,14 +87,16 @@ template<> struct mul31_unrolled_hash_impl<32>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct mul31_unrolled_hash_impl<64>
|
// mul31_x8_hash
|
||||||
|
|
||||||
|
struct mul31_x8_hash
|
||||||
{
|
{
|
||||||
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
|
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
char const * p = st.data();
|
char const * p = st.data();
|
||||||
std::size_t n = st.size();
|
std::size_t n = st.size();
|
||||||
|
|
||||||
std::size_t h = 0xCBF29CE484222325ull;
|
boost::uint64_t h = 0xCBF29CE484222325ull;
|
||||||
|
|
||||||
while( n >= 8 )
|
while( n >= 8 )
|
||||||
{
|
{
|
||||||
@@ -120,12 +122,10 @@ template<> struct mul31_unrolled_hash_impl<64>
|
|||||||
--n;
|
--n;
|
||||||
}
|
}
|
||||||
|
|
||||||
return h;
|
return static_cast<std::size_t>( h );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mul31_unrolled_hash: mul31_unrolled_hash_impl< std::numeric_limits<std::size_t>::digits > {};
|
|
||||||
|
|
||||||
// fnv1a_hash
|
// fnv1a_hash
|
||||||
|
|
||||||
template<int Bits> struct fnv1a_hash_impl;
|
template<int Bits> struct fnv1a_hash_impl;
|
||||||
@@ -363,7 +363,8 @@ int main()
|
|||||||
std::puts( "Hash speed test:\n" );
|
std::puts( "Hash speed test:\n" );
|
||||||
|
|
||||||
test_hash_speed<mul31_hash>( N * 16, v );
|
test_hash_speed<mul31_hash>( N * 16, v );
|
||||||
test_hash_speed<mul31_unrolled_hash>( N * 16, v );
|
test_hash_speed<mul31_x4_hash>( N * 16, v );
|
||||||
|
test_hash_speed<mul31_x8_hash>( N * 16, v );
|
||||||
test_hash_speed<fnv1a_hash>( N * 16, v );
|
test_hash_speed<fnv1a_hash>( N * 16, v );
|
||||||
test_hash_speed<boost::hash<std::string> >( N * 16, v );
|
test_hash_speed<boost::hash<std::string> >( N * 16, v );
|
||||||
test_hash_speed<std::hash<std::string> >( N * 16, v );
|
test_hash_speed<std::hash<std::string> >( N * 16, v );
|
||||||
@@ -396,7 +397,8 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
test_hash_collision<mul31_hash>( N * 16, v, n );
|
test_hash_collision<mul31_hash>( N * 16, v, n );
|
||||||
test_hash_collision<mul31_unrolled_hash>( N * 16, v, n );
|
test_hash_collision<mul31_x4_hash>( N * 16, v, n );
|
||||||
|
test_hash_collision<mul31_x8_hash>( N * 16, v, n );
|
||||||
test_hash_collision<fnv1a_hash>( N * 16, v, n );
|
test_hash_collision<fnv1a_hash>( N * 16, v, n );
|
||||||
test_hash_collision<boost::hash<std::string> >( N * 16, v, n );
|
test_hash_collision<boost::hash<std::string> >( N * 16, v, n );
|
||||||
test_hash_collision<std::hash<std::string> >( N * 16, v, n );
|
test_hash_collision<std::hash<std::string> >( N * 16, v, n );
|
||||||
@@ -418,7 +420,8 @@ int main()
|
|||||||
std::puts( "Container speed test:\n" );
|
std::puts( "Container speed test:\n" );
|
||||||
|
|
||||||
test_container_speed<K, mul31_hash>( N, v );
|
test_container_speed<K, mul31_hash>( N, v );
|
||||||
test_container_speed<K, mul31_unrolled_hash>( N, v );
|
test_container_speed<K, mul31_x4_hash>( N, v );
|
||||||
|
test_container_speed<K, mul31_x8_hash>( N, v );
|
||||||
test_container_speed<K, fnv1a_hash>( N, v );
|
test_container_speed<K, fnv1a_hash>( N, v );
|
||||||
test_container_speed<K, boost::hash<std::string> >( N, v );
|
test_container_speed<K, boost::hash<std::string> >( N, v );
|
||||||
test_container_speed<K, std::hash<std::string> >( N, v );
|
test_container_speed<K, std::hash<std::string> >( N, v );
|
||||||
|
@@ -212,10 +212,8 @@ template<class Hash> BOOST_NOINLINE void test( char const* label )
|
|||||||
|
|
||||||
// mul31_hash
|
// mul31_hash
|
||||||
|
|
||||||
class mul31_hash
|
struct mul31_hash
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
|
|
||||||
// not avalanching
|
// not avalanching
|
||||||
|
|
||||||
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
|
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
|
||||||
@@ -238,18 +236,22 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// mul31_unrolled_hash
|
// mul31_x4_hash
|
||||||
|
|
||||||
template<int Bits> struct mul31_unrolled_hash_impl;
|
struct mul31_x4_hash
|
||||||
|
|
||||||
template<> struct mul31_unrolled_hash_impl<32>
|
|
||||||
{
|
{
|
||||||
|
// not avalanching
|
||||||
|
|
||||||
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
|
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
char const * p = st.data();
|
char const * p = st.data();
|
||||||
std::size_t n = st.size();
|
std::size_t n = st.size();
|
||||||
|
|
||||||
|
#if SIZE_MAX > UINT32_MAX
|
||||||
|
std::size_t h = 0xCBF29CE484222325ull;
|
||||||
|
#else
|
||||||
std::size_t h = 0x811C9DC5u;
|
std::size_t h = 0x811C9DC5u;
|
||||||
|
#endif
|
||||||
|
|
||||||
while( n >= 4 )
|
while( n >= 4 )
|
||||||
{
|
{
|
||||||
@@ -275,14 +277,18 @@ template<> struct mul31_unrolled_hash_impl<32>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct mul31_unrolled_hash_impl<64>
|
// mul31_x8_hash
|
||||||
|
|
||||||
|
struct mul31_x8_hash
|
||||||
{
|
{
|
||||||
|
// not avalanching
|
||||||
|
|
||||||
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
|
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
char const * p = st.data();
|
char const * p = st.data();
|
||||||
std::size_t n = st.size();
|
std::size_t n = st.size();
|
||||||
|
|
||||||
std::size_t h = 0xCBF29CE484222325ull;
|
boost::uint64_t h = 0xCBF29CE484222325ull;
|
||||||
|
|
||||||
while( n >= 8 )
|
while( n >= 8 )
|
||||||
{
|
{
|
||||||
@@ -308,15 +314,10 @@ template<> struct mul31_unrolled_hash_impl<64>
|
|||||||
--n;
|
--n;
|
||||||
}
|
}
|
||||||
|
|
||||||
return h;
|
return static_cast<std::size_t>( h );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mul31_unrolled_hash: mul31_unrolled_hash_impl< std::numeric_limits<std::size_t>::digits >
|
|
||||||
{
|
|
||||||
// not avalanching
|
|
||||||
};
|
|
||||||
|
|
||||||
// fnv1a_hash
|
// fnv1a_hash
|
||||||
|
|
||||||
template<int Bits> struct fnv1a_hash_impl;
|
template<int Bits> struct fnv1a_hash_impl;
|
||||||
@@ -437,7 +438,8 @@ int main()
|
|||||||
test< boost::hash<std::string> >( "boost::hash" );
|
test< boost::hash<std::string> >( "boost::hash" );
|
||||||
test< std_hash >( "std::hash" );
|
test< std_hash >( "std::hash" );
|
||||||
test< mul31_hash >( "mul31_hash" );
|
test< mul31_hash >( "mul31_hash" );
|
||||||
test< mul31_unrolled_hash >( "mul31_unrolled_hash" );
|
test< mul31_x4_hash >( "mul31_x4_hash" );
|
||||||
|
test< mul31_x8_hash >( "mul31_x8_hash" );
|
||||||
test< fnv1a_hash >( "fnv1a_hash" );
|
test< fnv1a_hash >( "fnv1a_hash" );
|
||||||
|
|
||||||
#ifdef HAVE_ABSEIL
|
#ifdef HAVE_ABSEIL
|
||||||
|
Reference in New Issue
Block a user