[Bug libstdc++/54075] [4.7.1] unordered_map insert still slower than 4.6.2

François Dumont frs.dumont@gmail.com
Fri Nov 16 21:58:00 GMT 2012


Attached patch applied.

2012-11-16  François Dumont  <fdumont@gcc.gnu.org>

     * include/bits/hashtable_policy.h (_Prime_rehash_policy): Remove
     automatic shrink.
     (_Prime_rehash_policy::_M_bkt_for_elements): Do not call
     _M_next_bkt anymore.
     (_Prime_rehash_policy::_M_next_bkt): Move usage of
     _S_growth_factor ...
     (_Prime_rehash_policy::_M_need_rehash): ... here.
     * include/bits/hashtable.h (_Hashtable<>): Adapt.
     * testsuite/performance/23_containers/insert_erase/41975.cc: Add
     _USE_TR1 to force build using std::tr1 container.
     * testsuite/performance/23_containers/insert/unordered_set.cc:
     Likewise.
     * testsuite/performance/23_containers/insert/54075.cc: New.

Note that I have used std::random_device in 54075 test. I also preferred 
to test both std and std::tr1 containers in a single run without relying 
on a macro check. As long as we try to align std containers performance 
on tr1 ones it is better maybe later we could limit it to test only 
std:: container per default.

I have also added several use cases and here is the result:

54075.cc                     std::tr1::unordered_set without hash code 
cached 300000 Foo insertions      10r    9u    1s 13765616mem    0pf
54075.cc                     std::tr1::unordered_set without hash code 
cached 10 times insertion of 300000 Foo      21r   21u 0s        0mem    
0pf
54075.cc                     std::tr1::unordered_set with hash code 
cached 300000 Foo insertions      15r   14u    0s 18561984mem    0pf
54075.cc                     std::tr1::unordered_set with hash code 
cached 10 times insertion of 300000 Foo      23r   23u 0s        0mem    
0pf
54075.cc                     std::tr1::unordered_multiset without hash 
code cached 300000 Foo insertions       9r    8u    1s 13761968mem    0pf
54075.cc                     std::tr1::unordered_multiset without hash 
code cached 10 times insertion of 300000 Foo     113r 107u    7s 
126686848mem    0pf
54075.cc                     std::tr1::unordered_multiset with hash code 
cached 300000 Foo insertions     100r  100u    0s 18561984mem    0pf
54075.cc                     std::tr1::unordered_multiset with hash code 
cached 10 times insertion of 300000 Foo     111r 107u    4s 
174686864mem    0pf
54075.cc                     std::unordered_set without hash code cached 
300000 Foo insertions       9r    8u    1s 13761936mem 0pf
54075.cc                     std::unordered_set without hash code cached 
10 times insertion of 300000 Foo      34r   34u 0s        0mem    0pf
54075.cc                     std::unordered_set with hash code cached 
300000 Foo insertions      10r   10u    1s 18562000mem 0pf
54075.cc                     std::unordered_set with hash code cached 10 
times insertion of 300000 Foo      37r   37u 0s        0mem    0pf
54075.cc                     std::unordered_multiset without hash code 
cached 300000 Foo insertions       8r    9u    0s 13761936mem    0pf
54075.cc                     std::unordered_multiset without hash code 
cached 10 times insertion of 300000 Foo      34r   34u 0s        0mem    
0pf
54075.cc                     std::unordered_multiset with hash code 
cached 300000 Foo insertions      10r   10u    0s 18562000mem    0pf
54075.cc                     std::unordered_multiset with hash code 
cached 10 times insertion of 300000 Foo      37r   37u 0s        0mem    
0pf

     There is one surprising result; std::tr1::unordered_multiset is 
quite bad, I haven't check yet why and it is not my priority, I take it 
as a good news for the moment. The other important result is this one:
54075.cc                     std::tr1::unordered_set without hash code 
cached 10 times insertion of 300000 Foo      21r   21u 0s        0mem    0pf
54075.cc                     std::unordered_set without hash code cached 
10 times insertion of 300000 Foo      34r   34u 0s        0mem    0pf

     We can see that inserting the same elements again, that is to say 
detecting the collisions, is slower in the new implementation. It is the 
problem I had already signaled in bugzilla entry. In the new 
implementation when we need to look for bucket elements we have to check 
the hash code of each element to see if we are still in the same bucket, 
in the former there was a nullptr to signal the end of the bucket. I 
think I am going to try to add an empty node to mark the end of the 
bucket. It will introduce a memory tradeoff of one empty node for each 
non-empty bucket but it will also limit the impact of caching the hash 
code or node because we won't need to use it so often.

François



On 11/14/2012 11:54 AM, Paolo Carlini wrote:
> Hi,
>
> On 11/13/2012 10:40 PM, François Dumont wrote:
>> 2012-11-13 François Dumont <fdumont@gcc.gnu.org>
>>
>>     * include/bits/hashtable_policy.h (_Prime_rehash_policy): Remove
>>     automatic shrink.
>>     (_Prime_rehash_policy::_M_bkt_for_elements): Do not call
>>     _M_next_bkt anymore.
>>     (_Prime_rehash_policy::_M_next_bkt): Move usage of
>>     _S_growth_factor ...
>>     (_Prime_rehash_policy::_M_need_rehash): ... here.
>>     * include/bits/hashtable.h (_Hashtable<>): Adapt.
>>
>> Tested under linux x86_64, normal and debug modes.
> Patch is Ok with me, please wait another day or two for comments and 
> then apply it.
>
> You can also add the performance testcase, of course, note however 
> that ::random isn't a standard C function, thus we shouldn't use it 
> unconditionally, either manage with std::rand from <cstdlib> or do 
> something completely different (maybe even <random> since you are 
> writing C++11 code anyway!). I would also recommend extending quite a 
> bit the runtime, 10x would be still completely sensible (but I guess, 
> without using much more memory)
>
> Paolo.
>

-------------- next part --------------
A non-text attachment was scrubbed...
Name: hashtable.patch
Type: text/x-patch
Size: 12989 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20121116/6066674c/attachment.bin>


More information about the Libstdc++ mailing list