aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorFrançois Dumont <fdumont@gcc.gnu.org>2012-07-29 16:44:18 +0000
committerFrançois Dumont <fdumont@gcc.gnu.org>2012-07-29 16:44:18 +0000
commit78aa145d9ecdbcacc8f9a06022feb3a8f8e2dab2 (patch)
treee1573fe4e577579cd5aa5c3a14061a1736caa5c5 /libstdc++-v3
parent231464b2276ca9dc901182e006f811ad5caca637 (diff)
downloadgcc-78aa145d9ecdbcacc8f9a06022feb3a8f8e2dab2.zip
gcc-78aa145d9ecdbcacc8f9a06022feb3a8f8e2dab2.tar.gz
gcc-78aa145d9ecdbcacc8f9a06022feb3a8f8e2dab2.tar.bz2
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
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog8
-rw-r--r--libstdc++-v3/include/bits/hashtable_policy.h31
-rw-r--r--libstdc++-v3/testsuite/performance/23_containers/insert/unordered_set.cc42
3 files changed, 66 insertions, 15 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 407b061..6d6c06b 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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>
PR libstdc++/54075
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index c0a6df5..27790f2 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -395,6 +395,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
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;
mutable std::size_t _M_prev_resize;
mutable std::size_t _M_next_resize;
@@ -415,28 +417,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static const unsigned char __fast_bkt[12]
= { 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_next_resize
- = __builtin_ceil(__fast_bkt[__n] * (long double)_M_max_load_factor);
- return __fast_bkt[__n];
+ = __builtin_ceil(__fast_bkt[__grown_n]
+ * (long double)_M_max_load_factor);
+ return __fast_bkt[__grown_n];
}
- const unsigned long* __p
- = std::lower_bound(__prime_list + 5, __prime_list + _S_n_primes, __n);
+ const unsigned long* __next_bkt
+ = 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
- = __builtin_floor(*(__p - 2) * (long double)_M_max_load_factor);
-
- // Let's guaranty that a minimal grow step of 11 is used
- if (*__p - __n < 11)
- __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;
+ = __builtin_floor(*(__prev_bkt - 1) * (long double)_M_max_load_factor);
+ _M_next_resize
+ = __builtin_ceil(*__next_bkt * (long double)_M_max_load_factor);
+ return *__next_bkt;
}
// Return the smallest prime p such that alpha p >= n, where alpha
diff --git a/libstdc++-v3/testsuite/performance/23_containers/insert/unordered_set.cc b/libstdc++-v3/testsuite/performance/23_containers/insert/unordered_set.cc
new file mode 100644
index 0000000..83d3935
--- /dev/null
+++ b/libstdc++-v3/testsuite/performance/23_containers/insert/unordered_set.cc
@@ -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;
+}