re PR libstdc++/54075 ([4.7.1] unordered_map insert still slower than 4.6.2)
2012-07-29 François Dumont <fdumont@gcc.gnu.org> PR libstdc++/54075 * include/bits/hashtable_policy.h (_Prime_rehash_policy::_M_next_bkt): Add a growth factor set to 2 to boost growth in the number of buckets. * testsuite/performance/23_containers/insert/unordered_set.cc: New. From-SVN: r189938
This commit is contained in:
parent
231464b227
commit
78aa145d9e
|
@ -1,3 +1,11 @@
|
||||||
|
2012-07-29 François Dumont <fdumont@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR libstdc++/54075
|
||||||
|
* include/bits/hashtable_policy.h
|
||||||
|
(_Prime_rehash_policy::_M_next_bkt): Add a growth factor set to 2
|
||||||
|
to boost growth in the number of buckets.
|
||||||
|
* testsuite/performance/23_containers/insert/unordered_set.cc: New.
|
||||||
|
|
||||||
2012-07-25 François Dumont <fdumont@gcc.gnu.org>
|
2012-07-25 François Dumont <fdumont@gcc.gnu.org>
|
||||||
|
|
||||||
PR libstdc++/54075
|
PR libstdc++/54075
|
||||||
|
|
|
@ -395,6 +395,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
enum { _S_n_primes = sizeof(unsigned long) != 8 ? 256 : 256 + 48 };
|
enum { _S_n_primes = sizeof(unsigned long) != 8 ? 256 : 256 + 48 };
|
||||||
|
|
||||||
|
static const std::size_t _S_growth_factor = 2;
|
||||||
|
|
||||||
float _M_max_load_factor;
|
float _M_max_load_factor;
|
||||||
mutable std::size_t _M_prev_resize;
|
mutable std::size_t _M_prev_resize;
|
||||||
mutable std::size_t _M_next_resize;
|
mutable std::size_t _M_next_resize;
|
||||||
|
@ -415,28 +417,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
static const unsigned char __fast_bkt[12]
|
static const unsigned char __fast_bkt[12]
|
||||||
= { 2, 2, 2, 3, 5, 5, 7, 7, 11, 11, 11, 11 };
|
= { 2, 2, 2, 3, 5, 5, 7, 7, 11, 11, 11, 11 };
|
||||||
|
|
||||||
if (__n <= 11)
|
const std::size_t __grown_n = __n * _S_growth_factor;
|
||||||
|
if (__grown_n <= 11)
|
||||||
{
|
{
|
||||||
_M_prev_resize = 0;
|
_M_prev_resize = 0;
|
||||||
_M_next_resize
|
_M_next_resize
|
||||||
= __builtin_ceil(__fast_bkt[__n] * (long double)_M_max_load_factor);
|
= __builtin_ceil(__fast_bkt[__grown_n]
|
||||||
return __fast_bkt[__n];
|
* (long double)_M_max_load_factor);
|
||||||
|
return __fast_bkt[__grown_n];
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned long* __p
|
const unsigned long* __next_bkt
|
||||||
= std::lower_bound(__prime_list + 5, __prime_list + _S_n_primes, __n);
|
= std::lower_bound(__prime_list + 5, __prime_list + _S_n_primes,
|
||||||
|
__grown_n);
|
||||||
|
const unsigned long* __prev_bkt
|
||||||
|
= std::lower_bound(__prime_list + 1, __next_bkt, __n / _S_growth_factor);
|
||||||
|
|
||||||
// Shrink will take place only if the number of elements is small enough
|
|
||||||
// so that the prime number 2 steps before __p is large enough to still
|
|
||||||
// conform to the max load factor:
|
|
||||||
_M_prev_resize
|
_M_prev_resize
|
||||||
= __builtin_floor(*(__p - 2) * (long double)_M_max_load_factor);
|
= __builtin_floor(*(__prev_bkt - 1) * (long double)_M_max_load_factor);
|
||||||
|
_M_next_resize
|
||||||
// Let's guaranty that a minimal grow step of 11 is used
|
= __builtin_ceil(*__next_bkt * (long double)_M_max_load_factor);
|
||||||
if (*__p - __n < 11)
|
return *__next_bkt;
|
||||||
__p = std::lower_bound(__p, __prime_list + _S_n_primes, __n + 11);
|
|
||||||
_M_next_resize = __builtin_ceil(*__p * (long double)_M_max_load_factor);
|
|
||||||
return *__p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the smallest prime p such that alpha p >= n, where alpha
|
// Return the smallest prime p such that alpha p >= n, where alpha
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright (C) 2012 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=c++11" }
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <testsuite_performance.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
using namespace __gnu_test;
|
||||||
|
|
||||||
|
time_counter time;
|
||||||
|
resource_counter resource;
|
||||||
|
|
||||||
|
const int sz = 10000000;
|
||||||
|
|
||||||
|
std::unordered_set<int> s;
|
||||||
|
start_counters(time, resource);
|
||||||
|
|
||||||
|
for (int i = 0; i != sz ; ++i)
|
||||||
|
s.insert(i);
|
||||||
|
|
||||||
|
stop_counters(time, resource);
|
||||||
|
report_performance(__FILE__, "unordered_set 10000000 insertions",
|
||||||
|
time, resource);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue