mirror of
https://github.com/autc04/Retro68.git
synced 2024-09-06 22:54:33 +00:00
189 lines
4.9 KiB
C++
189 lines
4.9 KiB
C++
// Copyright (C) 2012-2016 Free Software Foundation, Inc.
|
|
//
|
|
// This file is part of the GNU ISO C++ Library. This library is free
|
|
// software; you can redistribute it and/or modify it under the
|
|
// terms of the GNU General Public License as published by the
|
|
// Free Software Foundation; either version 3, or (at your option)
|
|
// any later version.
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License along
|
|
// with this library; see the file COPYING3. If not see
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
// { dg-options "-std=gnu++11" }
|
|
|
|
#include <testsuite_performance.h>
|
|
#include <random>
|
|
#include <sstream>
|
|
#include <tr1/unordered_set>
|
|
#include <unordered_set>
|
|
|
|
#define USE_MY_FOO 1
|
|
|
|
struct Foo
|
|
{
|
|
#if USE_MY_FOO
|
|
|
|
typedef std::random_device::result_type _Type;
|
|
_Type bar;
|
|
_Type baz;
|
|
_Type meh;
|
|
|
|
void
|
|
init(std::random_device& randev)
|
|
{
|
|
bar = randev();
|
|
baz = randev();
|
|
meh = randev();
|
|
}
|
|
|
|
#else
|
|
|
|
int bar;
|
|
int baz;
|
|
int meh;
|
|
|
|
Foo()
|
|
{ bar = random(); baz = random(); meh = random(); }
|
|
Foo(const Foo&) = default;
|
|
|
|
#endif
|
|
|
|
std::size_t
|
|
hash() const noexcept
|
|
{ return std::size_t(bar ^ baz ^ meh); }
|
|
|
|
inline bool
|
|
operator==(const Foo& other) const
|
|
{ return other.bar == bar && other.baz == baz && other.meh == meh; }
|
|
};
|
|
|
|
struct HashFunction
|
|
{
|
|
template<typename T>
|
|
std::size_t operator()(const T& t) const noexcept
|
|
{ return t.hash(); }
|
|
};
|
|
|
|
const int sz = 300000;
|
|
|
|
template<typename _ContType>
|
|
void
|
|
bench(const char* container_desc, const typename _ContType::value_type* foos)
|
|
{
|
|
using namespace __gnu_test;
|
|
|
|
_ContType s;
|
|
|
|
time_counter time;
|
|
resource_counter resource;
|
|
start_counters(time, resource);
|
|
|
|
for (int i = 0; i != sz ; ++i)
|
|
s.insert(foos[i]);
|
|
|
|
stop_counters(time, resource);
|
|
std::ostringstream ostr;
|
|
ostr << container_desc << sz << " insertion attempts, "
|
|
<< s.size() << " inserted";
|
|
report_performance(__FILE__, ostr.str().c_str(), time, resource);
|
|
|
|
// Try to insert again to check performance of collision detection
|
|
const int nb_loop = 10;
|
|
start_counters(time, resource);
|
|
|
|
for (int j = 0; j != nb_loop; ++j)
|
|
for (int i = 0; i != sz; ++i)
|
|
s.insert(foos[i]);
|
|
|
|
stop_counters(time, resource);
|
|
ostr.str("");
|
|
ostr << container_desc << nb_loop << " times insertion of "
|
|
<< sz << " elements";
|
|
report_performance(__FILE__, ostr.str().c_str(), time, resource);
|
|
}
|
|
|
|
template<bool cache>
|
|
using __tr1_uset = std::tr1::__unordered_set<Foo, HashFunction,
|
|
std::equal_to<Foo>,
|
|
std::allocator<Foo>,
|
|
cache>;
|
|
template<bool cache>
|
|
using __tr1_umset = std::tr1::__unordered_multiset<Foo, HashFunction,
|
|
std::equal_to<Foo>,
|
|
std::allocator<Foo>,
|
|
cache>;
|
|
template<bool cache>
|
|
using __uset = std::__uset_hashtable<Foo, HashFunction,
|
|
std::equal_to<Foo>,
|
|
std::allocator<Foo>,
|
|
std::__uset_traits<cache>>;
|
|
template<bool cache>
|
|
using __umset = std::__umset_hashtable<Foo, HashFunction,
|
|
std::equal_to<Foo>,
|
|
std::allocator<Foo>,
|
|
std::__uset_traits<cache>>;
|
|
|
|
int main()
|
|
{
|
|
using namespace __gnu_test;
|
|
|
|
{
|
|
int bars[sz];
|
|
for (int i = 0; i != sz; ++i)
|
|
bars[i] = i;
|
|
bench<std::tr1::unordered_set<int>>(
|
|
"std::tr1::unordered_set<int> ", bars);
|
|
bench<std::unordered_set<int>>(
|
|
"std::unordered_set<int> ", bars);
|
|
}
|
|
|
|
Foo foos[sz];
|
|
#if USE_MY_FOO
|
|
{
|
|
std::random_device randev;
|
|
for (int i = 0; i != sz; ++i)
|
|
foos[i].init(randev);
|
|
}
|
|
#endif
|
|
|
|
time_counter time;
|
|
resource_counter resource;
|
|
start_counters(time, resource);
|
|
|
|
bench<__tr1_uset<false>>(
|
|
"std::tr1::unordered_set without hash code cached ", foos);
|
|
bench<__tr1_uset<true>>(
|
|
"std::tr1::unordered_set with hash code cached ", foos);
|
|
bench<__tr1_umset<false>>(
|
|
"std::tr1::unordered_multiset without hash code cached ", foos);
|
|
bench<__tr1_umset<true>>(
|
|
"std::tr1::unordered_multiset with hash code cached ", foos);
|
|
|
|
stop_counters(time, resource);
|
|
report_performance(__FILE__, "tr1 benches", time, resource);
|
|
|
|
start_counters(time, resource);
|
|
bench<__uset<false>>(
|
|
"std::unordered_set without hash code cached ", foos);
|
|
bench<__uset<true>>(
|
|
"std::unordered_set with hash code cached ", foos);
|
|
bench<__umset<false>>(
|
|
"std::unordered_multiset without hash code cached ", foos);
|
|
bench<__umset<true>>(
|
|
"std::unordered_multiset with hash code cached ", foos);
|
|
|
|
stop_counters(time, resource);
|
|
report_performance(__FILE__, "std benches", time, resource);
|
|
|
|
bench<std::unordered_set<Foo, HashFunction>>(
|
|
"std::unordered_set default cache ", foos);
|
|
bench<std::unordered_multiset<Foo, HashFunction>>(
|
|
"std::unordered_multiset default cache ", foos);
|
|
}
|