Compare commits

..

7 Commits

Author SHA1 Message Date
joaquintides f8d882b6eb optimized SSE2-based group15 2022-12-04 12:04:04 +01:00
Peter Dimov 9716731864 Disable benchmark/uint64.cpp under libstdc++ 32 bit 2022-12-03 15:37:22 +02:00
Peter Dimov 0bcd46a485 Use enwik8 instead of enwik9 in benchmarks under 32 bit 2022-12-03 15:32:04 +02:00
Peter Dimov 46a2cd109f Define _SILENCE_CXX20_CISO646_REMOVED_WARNING in benchmarks 2022-12-01 01:34:00 +02:00
Peter Dimov 808f8e659a Remove tsl maps from benchmarks 2022-12-01 01:30:54 +02:00
Peter Dimov 8ed05de91c Add ankerl::unordered_dense::map to benchmarks 2022-12-01 00:50:29 +02:00
Peter Dimov 1a02fca5c4 Add benchmark/.gitignore 2022-11-29 18:14:52 +02:00
9 changed files with 317 additions and 207 deletions
+3
View File
@@ -0,0 +1,3 @@
enwik8
enwik9
*.exe
+22 -66
View File
@@ -3,6 +3,7 @@
// https://www.boost.org/LICENSE_1_0.txt
#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING
#define _SILENCE_CXX20_CISO646_REMOVED_WARNING
#include <boost/unordered_map.hpp>
#include <boost/unordered/unordered_flat_map.hpp>
@@ -12,11 +13,8 @@
# include "absl/container/node_hash_map.h"
# include "absl/container/flat_hash_map.h"
#endif
#ifdef HAVE_TSL_HOPSCOTCH
# include "tsl/hopscotch_map.h"
#endif
#ifdef HAVE_TSL_ROBIN
# include "tsl/robin_map.h"
#ifdef HAVE_ANKERL_UNORDERED_DENSE
# include "ankerl/unordered_dense.h"
#endif
#include <unordered_map>
#include <vector>
@@ -287,23 +285,10 @@ template<class K, class V> using absl_flat_hash_map =
#endif
#ifdef HAVE_TSL_HOPSCOTCH
#ifdef HAVE_ANKERL_UNORDERED_DENSE
template<class K, class V> using tsl_hopscotch_map =
tsl::hopscotch_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_hopscotch_pg_map =
tsl::hopscotch_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
#ifdef HAVE_TSL_ROBIN
template<class K, class V> using tsl_robin_map =
tsl::robin_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_robin_pg_map =
tsl::robin_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using ankerl_unordered_dense_map =
ankerl::unordered_dense::map<K, V, ankerl::unordered_dense::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
@@ -373,23 +358,10 @@ template<class K, class V> using absl_flat_hash_map_fnv1a =
#endif
#ifdef HAVE_TSL_HOPSCOTCH
#ifdef HAVE_ANKERL_UNORDERED_DENSE
template<class K, class V> using tsl_hopscotch_map_fnv1a =
tsl::hopscotch_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_hopscotch_pg_map_fnv1a =
tsl::hopscotch_pg_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
#ifdef HAVE_TSL_ROBIN
template<class K, class V> using tsl_robin_map_fnv1a =
tsl::robin_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_robin_pg_map_fnv1a =
tsl::robin_pg_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using ankerl_unordered_dense_map_fnv1a =
ankerl::unordered_dense::map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
@@ -403,57 +375,41 @@ int main()
test<boost_unordered_map>( "boost::unordered_map" );
test<boost_unordered_flat_map>( "boost::unordered_flat_map" );
#ifdef HAVE_ANKERL_UNORDERED_DENSE
test<ankerl_unordered_dense_map>( "ankerl::unordered_dense::map" );
#endif
#ifdef HAVE_ABSEIL
test<absl_node_hash_map>( "absl::node_hash_map" );
test<absl_flat_hash_map>( "absl::flat_hash_map" );
#endif
#ifdef HAVE_TSL_HOPSCOTCH
test<tsl_hopscotch_map>( "tsl::hopscotch_map" );
test<tsl_hopscotch_pg_map>( "tsl::hopscotch_pg_map" );
#endif
#ifdef HAVE_TSL_ROBIN
test<tsl_robin_map>( "tsl::robin_map" );
test<tsl_robin_pg_map>( "tsl::robin_pg_map" );
#endif
test<std_unordered_map_fnv1a>( "std::unordered_map, FNV-1a" );
test<boost_unordered_map_fnv1a>( "boost::unordered_map, FNV-1a" );
test<boost_unordered_flat_map_fnv1a>( "boost::unordered_flat_map, FNV-1a" );
#ifdef HAVE_ANKERL_UNORDERED_DENSE
test<ankerl_unordered_dense_map_fnv1a>( "ankerl::unordered_dense::map, FNV-1a" );
#endif
#ifdef HAVE_ABSEIL
test<absl_node_hash_map_fnv1a>( "absl::node_hash_map, FNV-1a" );
test<absl_flat_hash_map_fnv1a>( "absl::flat_hash_map, FNV-1a" );
#endif
#ifdef HAVE_TSL_HOPSCOTCH
test<tsl_hopscotch_map_fnv1a>( "tsl::hopscotch_map, FNV-1a" );
test<tsl_hopscotch_pg_map_fnv1a>( "tsl::hopscotch_pg_map, FNV-1a" );
#endif
#ifdef HAVE_TSL_ROBIN
test<tsl_robin_map_fnv1a>( "tsl::robin_map, FNV-1a" );
test<tsl_robin_pg_map_fnv1a>( "tsl::robin_pg_map, FNV-1a" );
#endif
std::cout << "---\n\n";
for( auto const& x: times )
{
std::cout << std::setw( 35 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
std::cout << std::setw( 38 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
}
}
+22 -66
View File
@@ -3,6 +3,7 @@
// https://www.boost.org/LICENSE_1_0.txt
#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING
#define _SILENCE_CXX20_CISO646_REMOVED_WARNING
#include <boost/unordered_map.hpp>
#include <boost/unordered/unordered_flat_map.hpp>
@@ -12,11 +13,8 @@
# include "absl/container/node_hash_map.h"
# include "absl/container/flat_hash_map.h"
#endif
#ifdef HAVE_TSL_HOPSCOTCH
# include "tsl/hopscotch_map.h"
#endif
#ifdef HAVE_TSL_ROBIN
# include "tsl/robin_map.h"
#ifdef HAVE_ANKERL_UNORDERED_DENSE
# include "ankerl/unordered_dense.h"
#endif
#include <unordered_map>
#include <string_view>
@@ -288,23 +286,10 @@ template<class K, class V> using absl_flat_hash_map =
#endif
#ifdef HAVE_TSL_HOPSCOTCH
#ifdef HAVE_ANKERL_UNORDERED_DENSE
template<class K, class V> using tsl_hopscotch_map =
tsl::hopscotch_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_hopscotch_pg_map =
tsl::hopscotch_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
#ifdef HAVE_TSL_ROBIN
template<class K, class V> using tsl_robin_map =
tsl::robin_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_robin_pg_map =
tsl::robin_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using ankerl_unordered_dense_map =
ankerl::unordered_dense::map<K, V, ankerl::unordered_dense::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
@@ -374,23 +359,10 @@ template<class K, class V> using absl_flat_hash_map_fnv1a =
#endif
#ifdef HAVE_TSL_HOPSCOTCH
#ifdef HAVE_ANKERL_UNORDERED_DENSE
template<class K, class V> using tsl_hopscotch_map_fnv1a =
tsl::hopscotch_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_hopscotch_pg_map_fnv1a =
tsl::hopscotch_pg_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
#ifdef HAVE_TSL_ROBIN
template<class K, class V> using tsl_robin_map_fnv1a =
tsl::robin_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_robin_pg_map_fnv1a =
tsl::robin_pg_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using ankerl_unordered_dense_map_fnv1a =
ankerl::unordered_dense::map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
@@ -404,57 +376,41 @@ int main()
test<boost_unordered_map>( "boost::unordered_map" );
test<boost_unordered_flat_map>( "boost::unordered_flat_map" );
#ifdef HAVE_ANKERL_UNORDERED_DENSE
test<ankerl_unordered_dense_map>( "ankerl::unordered_dense::map" );
#endif
#ifdef HAVE_ABSEIL
test<absl_node_hash_map>( "absl::node_hash_map" );
test<absl_flat_hash_map>( "absl::flat_hash_map" );
#endif
#ifdef HAVE_TSL_HOPSCOTCH
test<tsl_hopscotch_map>( "tsl::hopscotch_map" );
test<tsl_hopscotch_pg_map>( "tsl::hopscotch_pg_map" );
#endif
#ifdef HAVE_TSL_ROBIN
test<tsl_robin_map>( "tsl::robin_map" );
test<tsl_robin_pg_map>( "tsl::robin_pg_map" );
#endif
test<std_unordered_map_fnv1a>( "std::unordered_map, FNV-1a" );
test<boost_unordered_map_fnv1a>( "boost::unordered_map, FNV-1a" );
test<boost_unordered_flat_map_fnv1a>( "boost::unordered_flat_map, FNV-1a" );
#ifdef HAVE_ANKERL_UNORDERED_DENSE
test<ankerl_unordered_dense_map_fnv1a>( "ankerl::unordered_dense::map, FNV-1a" );
#endif
#ifdef HAVE_ABSEIL
test<absl_node_hash_map_fnv1a>( "absl::node_hash_map, FNV-1a" );
test<absl_flat_hash_map_fnv1a>( "absl::flat_hash_map, FNV-1a" );
#endif
#ifdef HAVE_TSL_HOPSCOTCH
test<tsl_hopscotch_map_fnv1a>( "tsl::hopscotch_map, FNV-1a" );
test<tsl_hopscotch_pg_map_fnv1a>( "tsl::hopscotch_pg_map, FNV-1a" );
#endif
#ifdef HAVE_TSL_ROBIN
test<tsl_robin_map_fnv1a>( "tsl::robin_map, FNV-1a" );
test<tsl_robin_pg_map_fnv1a>( "tsl::robin_pg_map, FNV-1a" );
#endif
std::cout << "---\n\n";
for( auto const& x: times )
{
std::cout << std::setw( 35 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
std::cout << std::setw( 38 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
}
}
+13 -36
View File
@@ -3,6 +3,7 @@
// https://www.boost.org/LICENSE_1_0.txt
#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING
#define _SILENCE_CXX20_CISO646_REMOVED_WARNING
#include <boost/unordered_map.hpp>
#include <boost/unordered/unordered_flat_map.hpp>
@@ -13,11 +14,8 @@
# include "absl/container/node_hash_map.h"
# include "absl/container/flat_hash_map.h"
#endif
#ifdef HAVE_TSL_HOPSCOTCH
# include "tsl/hopscotch_map.h"
#endif
#ifdef HAVE_TSL_ROBIN
# include "tsl/robin_map.h"
#ifdef HAVE_ANKERL_UNORDERED_DENSE
# include "ankerl/unordered_dense.h"
#endif
#include <unordered_map>
#include <vector>
@@ -304,23 +302,10 @@ template<class K, class V> using absl_flat_hash_map =
#endif
#ifdef HAVE_TSL_HOPSCOTCH
#ifdef HAVE_ANKERL_UNORDERED_DENSE
template<class K, class V> using tsl_hopscotch_map =
tsl::hopscotch_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_hopscotch_pg_map =
tsl::hopscotch_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
#ifdef HAVE_TSL_ROBIN
template<class K, class V> using tsl_robin_map =
tsl::robin_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_robin_pg_map =
tsl::robin_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using ankerl_unordered_dense_map =
ankerl::unordered_dense::map<K, V, ankerl::unordered_dense::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
@@ -332,32 +317,24 @@ int main()
test<boost_unordered_map>( "boost::unordered_map" );
test<boost_unordered_flat_map>( "boost::unordered_flat_map" );
#ifdef HAVE_ANKERL_UNORDERED_DENSE
test<ankerl_unordered_dense_map>( "ankerl::unordered_dense::map" );
#endif
#ifdef HAVE_ABSEIL
test<absl_node_hash_map>( "absl::node_hash_map" );
test<absl_flat_hash_map>( "absl::flat_hash_map" );
#endif
#ifdef HAVE_TSL_HOPSCOTCH
test<tsl_hopscotch_map>( "tsl::hopscotch_map" );
test<tsl_hopscotch_pg_map>( "tsl::hopscotch_pg_map" );
#endif
#ifdef HAVE_TSL_ROBIN
test<tsl_robin_map>( "tsl::robin_map" );
test<tsl_robin_pg_map>( "tsl::robin_pg_map" );
#endif
std::cout << "---\n\n";
for( auto const& x: times )
{
std::cout << std::setw( 27 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
std::cout << std::setw( 30 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
}
}
+23 -36
View File
@@ -3,6 +3,7 @@
// https://www.boost.org/LICENSE_1_0.txt
#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING
#define _SILENCE_CXX20_CISO646_REMOVED_WARNING
#include <boost/unordered_map.hpp>
#include <boost/unordered/unordered_flat_map.hpp>
@@ -13,11 +14,8 @@
# include "absl/container/node_hash_map.h"
# include "absl/container/flat_hash_map.h"
#endif
#ifdef HAVE_TSL_HOPSCOTCH
# include "tsl/hopscotch_map.h"
#endif
#ifdef HAVE_TSL_ROBIN
# include "tsl/robin_map.h"
#ifdef HAVE_ANKERL_UNORDERED_DENSE
# include "ankerl/unordered_dense.h"
#endif
#include <unordered_map>
#include <vector>
@@ -304,23 +302,10 @@ template<class K, class V> using absl_flat_hash_map =
#endif
#ifdef HAVE_TSL_HOPSCOTCH
#ifdef HAVE_ANKERL_UNORDERED_DENSE
template<class K, class V> using tsl_hopscotch_map =
tsl::hopscotch_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_hopscotch_pg_map =
tsl::hopscotch_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
#ifdef HAVE_TSL_ROBIN
template<class K, class V> using tsl_robin_map =
tsl::robin_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_robin_pg_map =
tsl::robin_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using ankerl_unordered_dense_map =
ankerl::unordered_dense::map<K, V, ankerl::unordered_dense::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
@@ -328,36 +313,38 @@ int main()
{
init_indices();
#if defined(BOOST_LIBSTDCXX_VERSION) && __SIZE_WIDTH__ == 32
// Pathological behavior:
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104945
#else
test<std_unordered_map>( "std::unordered_map" );
#endif
test<boost_unordered_map>( "boost::unordered_map" );
test<boost_unordered_flat_map>( "boost::unordered_flat_map" );
#ifdef HAVE_ANKERL_UNORDERED_DENSE
test<ankerl_unordered_dense_map>( "ankerl::unordered_dense::map" );
#endif
#ifdef HAVE_ABSEIL
test<absl_node_hash_map>( "absl::node_hash_map" );
test<absl_flat_hash_map>( "absl::flat_hash_map" );
#endif
#ifdef HAVE_TSL_HOPSCOTCH
test<tsl_hopscotch_map>( "tsl::hopscotch_map" );
test<tsl_hopscotch_pg_map>( "tsl::hopscotch_pg_map" );
#endif
#ifdef HAVE_TSL_ROBIN
test<tsl_robin_map>( "tsl::robin_map" );
test<tsl_robin_pg_map>( "tsl::robin_pg_map" );
#endif
std::cout << "---\n\n";
for( auto const& x: times )
{
std::cout << std::setw( 27 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
std::cout << std::setw( 30 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
}
}
+18 -1
View File
@@ -3,6 +3,7 @@
// https://www.boost.org/LICENSE_1_0.txt
#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING
#define _SILENCE_CXX20_CISO646_REMOVED_WARNING
#include <boost/unordered_map.hpp>
#include <boost/unordered/unordered_flat_map.hpp>
@@ -14,6 +15,9 @@
# include "absl/container/node_hash_map.h"
# include "absl/container/flat_hash_map.h"
#endif
#ifdef HAVE_ANKERL_UNORDERED_DENSE
# include "ankerl/unordered_dense.h"
#endif
#include <unordered_map>
#include <vector>
#include <memory>
@@ -349,6 +353,13 @@ template<class K, class V> using absl_flat_hash_map =
#endif
#ifdef HAVE_ANKERL_UNORDERED_DENSE
template<class K, class V> using ankerl_unordered_dense_map =
ankerl::unordered_dense::map<K, V, ankerl::unordered_dense::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
int main()
{
init_indices();
@@ -357,6 +368,12 @@ int main()
test<boost_unordered_map>( "boost::unordered_map" );
test<boost_unordered_flat_map>( "boost::unordered_flat_map" );
#ifdef HAVE_ANKERL_UNORDERED_DENSE
test<ankerl_unordered_dense_map>( "ankerl::unordered_dense::map" );
#endif
#ifdef HAVE_ABSEIL
test<absl_node_hash_map>( "absl::node_hash_map" );
@@ -368,7 +385,7 @@ int main()
for( auto const& x: times )
{
std::cout << std::setw( 27 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
std::cout << std::setw( 30 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
}
}
+38 -1
View File
@@ -12,6 +12,9 @@
# include "absl/container/node_hash_map.h"
# include "absl/container/flat_hash_map.h"
#endif
#ifdef HAVE_ANKERL_UNORDERED_DENSE
# include "ankerl/unordered_dense.h"
#endif
#include <unordered_map>
#include <vector>
#include <memory>
@@ -38,8 +41,16 @@ static std::vector<std::string> words;
static void init_words()
{
#if SIZE_MAX > UINT32_MAX
char const* fn = "enwik9"; // http://mattmahoney.net/dc/textdata
#else
char const* fn = "enwik8"; // ditto
#endif
auto t1 = std::chrono::steady_clock::now();
std::ifstream is( fn );
@@ -229,6 +240,13 @@ template<class K, class V> using absl_flat_hash_map =
#endif
#ifdef HAVE_ANKERL_UNORDERED_DENSE
template<class K, class V> using ankerl_unordered_dense_map =
ankerl::unordered_dense::map<K, V, ankerl::unordered_dense::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
// fnv1a_hash
template<int Bits> struct fnv1a_hash_impl;
@@ -295,6 +313,13 @@ template<class K, class V> using absl_flat_hash_map_fnv1a =
#endif
#ifdef HAVE_ANKERL_UNORDERED_DENSE
template<class K, class V> using ankerl_unordered_dense_map_fnv1a =
ankerl::unordered_dense::map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
//
int main()
@@ -305,6 +330,12 @@ int main()
test<boost_unordered_map>( "boost::unordered_map" );
test<boost_unordered_flat_map>( "boost::unordered_flat_map" );
#ifdef HAVE_ANKERL_UNORDERED_DENSE
test<ankerl_unordered_dense_map>( "ankerl::unordered_dense::map" );
#endif
#ifdef HAVE_ABSEIL
test<absl_node_hash_map>( "absl::node_hash_map" );
@@ -316,6 +347,12 @@ int main()
test<boost_unordered_map_fnv1a>( "boost::unordered_map, FNV-1a" );
test<boost_unordered_flat_map_fnv1a>( "boost::unordered_flat_map, FNV-1a" );
#ifdef HAVE_ANKERL_UNORDERED_DENSE
test<ankerl_unordered_dense_map_fnv1a>( "ankerl::unordered_dense::map, FNV-1a" );
#endif
#ifdef HAVE_ABSEIL
test<absl_node_hash_map_fnv1a>( "absl::node_hash_map, FNV-1a" );
@@ -327,7 +364,7 @@ int main()
for( auto const& x: times )
{
std::cout << std::setw( 35 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
std::cout << std::setw( 38 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
}
}
+26 -1
View File
@@ -3,6 +3,7 @@
// https://www.boost.org/LICENSE_1_0.txt
#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING
#define _SILENCE_CXX20_CISO646_REMOVED_WARNING
#include <boost/unordered_map.hpp>
#include <boost/unordered/unordered_flat_map.hpp>
@@ -11,6 +12,9 @@
# include "absl/container/node_hash_map.h"
# include "absl/container/flat_hash_map.h"
#endif
#ifdef HAVE_ANKERL_UNORDERED_DENSE
# include "ankerl/unordered_dense.h"
#endif
#include <unordered_map>
#include <vector>
#include <memory>
@@ -35,8 +39,16 @@ static std::vector<std::string> words;
static void init_words()
{
#if SIZE_MAX > UINT32_MAX
char const* fn = "enwik9"; // http://mattmahoney.net/dc/textdata
#else
char const* fn = "enwik8"; // ditto
#endif
auto t1 = std::chrono::steady_clock::now();
std::ifstream is( fn );
@@ -182,6 +194,13 @@ template<class K, class V> using absl_flat_hash_map =
#endif
#ifdef HAVE_ANKERL_UNORDERED_DENSE
template<class K, class V> using ankerl_unordered_dense_map =
ankerl::unordered_dense::map<K, V, ankerl::unordered_dense::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
int main()
{
init_words();
@@ -190,6 +209,12 @@ int main()
test<boost_unordered_map>( "boost::unordered_map" );
test<boost_unordered_flat_map>( "boost::unordered_flat_map" );
#ifdef HAVE_ANKERL_UNORDERED_DENSE
test<ankerl_unordered_dense_map>( "ankerl::unordered_dense::map" );
#endif
#ifdef HAVE_ABSEIL
test<absl_node_hash_map>( "absl::node_hash_map" );
@@ -201,7 +226,7 @@ int main()
for( auto const& x: times )
{
std::cout << std::setw( 27 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
std::cout << std::setw( 30 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
}
}
+152
View File
@@ -135,6 +135,7 @@ static const std::size_t default_bucket_count = 0;
#if defined(BOOST_UNORDERED_SSE2)
#if 0
struct group15
{
static constexpr int N=15;
@@ -299,6 +300,157 @@ private:
alignas(16) __m128i m;
};
#else
struct group15
{
static constexpr int N=15;
struct dummy_group_type
{
alignas(16) unsigned char storage[N+1]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0};
};
inline void initialize(){m=_mm_setzero_si128();}
inline void set(std::size_t pos,std::size_t hash)
{
BOOST_ASSERT(pos<N);
at(pos)=reduced_hash(hash+pos);
}
inline void set_sentinel()
{
at(N-1)=sentinel_;
}
inline bool is_sentinel(std::size_t pos)const
{
BOOST_ASSERT(pos<N);
return at(pos)==sentinel_;
}
inline void reset(std::size_t pos)
{
BOOST_ASSERT(pos<N);
at(pos)=available_;
}
static inline void reset(unsigned char* pc)
{
*pc=available_;
}
inline int match(std::size_t hash)const
{
return _mm_movemask_epi8(_mm_cmpeq_epi8(m,match_word(hash)))&0x7FFF;
}
inline bool is_not_overflowed(std::size_t hash)const
{
static constexpr unsigned char shift[]={1,2,4,8,16,32,64,128};
return !(overflow()&shift[hash%8]);
}
inline void mark_overflow(std::size_t hash)
{
#if BOOST_WORKAROUND(BOOST_GCC, >= 50000 && BOOST_GCC < 60000)
overflow() = static_cast<unsigned char>( overflow() | static_cast<unsigned char>(1<<(hash%8)) );
#else
overflow()|=static_cast<unsigned char>(1<<(hash%8));
#endif
}
static inline bool maybe_caused_overflow(unsigned char* pc)
{
std::size_t pos=reinterpret_cast<uintptr_t>(pc)%sizeof(group15);
group15 *pg=reinterpret_cast<group15*>(pc-pos);
return !pg->is_not_overflowed(*pc-pos);
};
inline int match_available()const
{
return _mm_movemask_epi8(
_mm_cmpeq_epi8(m,_mm_setzero_si128()))&0x7FFF;
}
inline int match_occupied()const
{
return (~match_available())&0x7FFF;
}
inline int match_really_occupied()const /* excluding sentinel */
{
return at(N-1)==sentinel_?match_occupied()&0x3FFF:match_occupied();
}
private:
static constexpr unsigned char available_=0,
sentinel_=1;
static constexpr unsigned char reduced_hash_table[]={
8,9,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
8,9,2,3,4,5,6,7,8,9,10,11,12,13,14,
};
inline static __m128i match_word(std::size_t hash)
{
#if defined(__MSVC_RUNTIME_CHECKS)
return _mm_loadu_si128(reinterpret_cast<const __m128i*>(
reduced_hash_table+(hash&0xffu)));
#else
return _mm_loadu_si128(reinterpret_cast<const __m128i*>(
reduced_hash_table+(unsigned char)(hash)));
#endif
}
inline static unsigned char reduced_hash(std::size_t hash)
{
#if defined(__MSVC_RUNTIME_CHECKS)
return reduced_hash_table[hash&0xffu];
#else
return reduced_hash_table[(unsigned char)hash];
#endif
}
inline unsigned char& at(std::size_t pos)
{
return reinterpret_cast<unsigned char*>(&m)[pos];
}
inline unsigned char at(std::size_t pos)const
{
return reinterpret_cast<const unsigned char*>(&m)[pos];
}
inline unsigned char& overflow()
{
return at(N);
}
inline unsigned char overflow()const
{
return at(N);
}
alignas(16) __m128i m;
};
#endif
#elif defined(BOOST_UNORDERED_LITTLE_ENDIAN_NEON)