From e562aecb73a663da7fe9f777ef7e00e5c478cc4a Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Wed, 25 Feb 2009 18:58:48 +0100 Subject: [PATCH] HashTable performance: find(), found() check nElmts_ instead of tableSize_ - much better performance on empty tables (4-6x speedup), neutral performance change on filled tables. Since tableSize_ is non-zero when nElmts_ is, there is no modulus zero problem. --- .../test/PackedList2/PackedListTest2.C | 22 +++++++++++++- .../containers/HashTables/HashSet/HashSet.C | 20 ++++++------- .../HashTables/HashTable/HashTable.C | 30 +++++++++---------- .../HashTables/HashTable/HashTableI.H | 24 +++++++++++---- .../HashTables/HashTable/HashTableIO.C | 9 ++++-- .../StaticHashTable/StaticHashTable.C | 30 +++++++++++-------- .../StaticHashTable/StaticHashTableI.H | 2 +- .../StaticHashTable/StaticHashTableIO.C | 5 +++- 8 files changed, 94 insertions(+), 48 deletions(-) diff --git a/applications/test/PackedList2/PackedListTest2.C b/applications/test/PackedList2/PackedListTest2.C index 22282058ac..78f0f9f914 100644 --- a/applications/test/PackedList2/PackedListTest2.C +++ b/applications/test/PackedList2/PackedListTest2.C @@ -32,6 +32,7 @@ Description #include "boolList.H" #include "PackedBoolList.H" #include "HashSet.H" +#include "StaticHashTable.H" #include "cpuTime.H" #include @@ -55,11 +56,14 @@ int main(int argc, char *argv[]) labelHashSet emptyHash; labelHashSet fullHash(1000); - for(label i = 0; i < n; i++) + for (label i = 0; i < n; i++) { fullHash.insert(i); } + // don't use fullStaticHash, it's too slow + StaticHashTable > emptyStaticHash; + cpuTime timer; for (label iter = 0; iter < nIters; ++iter) @@ -235,6 +239,22 @@ int main(int argc, char *argv[]) Info<< " sum " << sum << endl; + // Read empty static hash + sum = 0; + for (label iter = 0; iter < nIters; ++iter) + { + forAll(unpacked, i) + { + sum += emptyStaticHash.found(i); + } + } + Info<< "Reading empty StaticHash:" << timer.cpuTimeIncrement() + << " s" << endl; + Info<< " sum " << sum << endl; + + + Info<< "Starting write tests" << endl; + // // Write // diff --git a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C index 6bf84e0c55..d63921f95b 100644 --- a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C +++ b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C @@ -33,14 +33,14 @@ License template template -Foam::HashSet::HashSet(const HashTable& ht) +Foam::HashSet::HashSet(const HashTable& h) : - HashTable(ht.size()) + HashTable(h.size()) { for ( - typename HashTable::const_iterator cit = ht.begin(); - cit != ht.end(); + typename HashTable::const_iterator cit = h.cbegin(); + cit != h.cend(); ++cit ) { @@ -62,7 +62,7 @@ template bool Foam::HashSet::operator==(const HashSet& rhs) const { // Are all lhs elements in rhs? - for (const_iterator iter = this->begin(); iter != this->end(); ++iter) + for (const_iterator iter = this->cbegin(); iter != this->cend(); ++iter) { if (!rhs.found(iter.key())) { @@ -71,7 +71,7 @@ bool Foam::HashSet::operator==(const HashSet& rhs) const } // Are all rhs elements in lhs? - for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter) + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) { if (!found(iter.key())) { @@ -94,7 +94,7 @@ template void Foam::HashSet::operator|=(const HashSet& rhs) { // Add rhs elements into lhs - for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter) + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) { insert(iter.key()); } @@ -105,7 +105,7 @@ template void Foam::HashSet::operator&=(const HashSet& rhs) { // Remove elements not also found in rhs - for (iterator iter = this->begin(); iter != this->end(); ++iter) + for (iterator iter = this->cbegin(); iter != this->cend(); ++iter) { if (!rhs.found(iter.key())) { @@ -119,7 +119,7 @@ template void Foam::HashSet::operator^=(const HashSet& rhs) { // Add missed rhs elements, remove duplicate elements - for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter) + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) { if (found(iter.key())) { @@ -138,7 +138,7 @@ template void Foam::HashSet::operator-=(const HashSet& rhs) { // Remove rhs elements from lhs - for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter) + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) { erase(iter.key()); } diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C index 3ed474b32d..e1def941d6 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C @@ -71,7 +71,7 @@ Foam::HashTable::HashTable(const HashTable& ht) table_[hashIdx] = 0; } - for (const_iterator iter = ht.begin(); iter != ht.end(); ++iter) + for (const_iterator iter = ht.cbegin(); iter != ht.cend(); ++iter) { insert(iter.key(), *iter); } @@ -113,9 +113,9 @@ Foam::HashTable::~HashTable() template bool Foam::HashTable::found(const Key& key) const { - if (tableSize_) + if (nElmts_) { - label hashIdx = Hash()(key, tableSize_); + const label hashIdx = Hash()(key, tableSize_); for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_) { @@ -145,9 +145,9 @@ Foam::HashTable::find const Key& key ) { - if (tableSize_) + if (nElmts_) { - label hashIdx = Hash()(key, tableSize_); + const label hashIdx = Hash()(key, tableSize_); for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_) { @@ -177,7 +177,7 @@ Foam::HashTable::find const Key& key ) const { - if (tableSize_) + if (nElmts_) { label hashIdx = Hash()(key, tableSize_); @@ -198,7 +198,7 @@ Foam::HashTable::find } # endif - return end(); + return cend(); } @@ -209,7 +209,7 @@ Foam::List Foam::HashTable::toc() const List tofc(nElmts_); label i = 0; - for (const_iterator iter = begin(); iter != end(); ++iter) + for (const_iterator iter = cbegin(); iter != cend(); ++iter) { tofc[i++] = iter.key(); } @@ -351,7 +351,7 @@ bool Foam::HashTable::erase(const iterator& cit) else { // No previous found. Mark with special value which is - // - not end() + // - not end()/cend() // - handled by operator++ it.elmtPtr_ = reinterpret_cast(this); it.hashIndex_ = -1; @@ -466,7 +466,7 @@ void Foam::HashTable::resize(const label newSize) HashTable* newTable = new HashTable(newSize); - for (const_iterator iter = begin(); iter != end(); ++iter) + for (const_iterator iter = cbegin(); iter != cend(); ++iter) { newTable->insert(iter.key(), *iter); } @@ -565,7 +565,7 @@ void Foam::HashTable::operator= clear(); } - for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter) + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) { insert(iter.key(), *iter); } @@ -579,22 +579,22 @@ bool Foam::HashTable::operator== ) const { // Are all my elements in rhs? - for (const_iterator iter = begin(); iter != end(); ++iter) + for (const_iterator iter = cbegin(); iter != cend(); ++iter) { const_iterator fnd = rhs.find(iter.key()); - if (fnd == rhs.end() || fnd() != iter()) + if (fnd == rhs.cend() || fnd() != iter()) { return false; } } // Are all rhs elements in me? - for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter) + for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) { const_iterator fnd = find(iter.key()); - if (fnd == end() || fnd() != iter()) + if (fnd == cend() || fnd() != iter()) { return false; } diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H b/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H index aea5f3043a..f117a601b9 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H @@ -112,7 +112,7 @@ inline const T& Foam::HashTable::operator[](const Key& key) const { const_iterator iter = find(key); - if (iter == end()) + if (iter == cend()) { FatalErrorIn("HashTable::operator[](const Key&) const") << key << " not found in table. Valid entries: " @@ -283,8 +283,15 @@ Foam::HashTable::begin() { label i = 0; - while (table_ && !table_[i] && ++i < tableSize_) - {} + if (nElmts_) + { + while (table_ && !table_[i] && ++i < tableSize_) + {} + } + else + { + i = tableSize_; + } if (i == tableSize_) { @@ -456,8 +463,15 @@ Foam::HashTable::cbegin() const { label i = 0; - while (table_ && !table_[i] && ++i < tableSize_) - {} + if (nElmts_) + { + while (table_ && !table_[i] && ++i < tableSize_) + {} + } + else + { + i = tableSize_; + } if (i == tableSize_) { diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTableIO.C b/src/OpenFOAM/containers/HashTables/HashTable/HashTableIO.C index d0251f5f21..4daab805c0 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTableIO.C +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTableIO.C @@ -39,7 +39,7 @@ Foam::HashTable::HashTable(Istream& is, const label size) endIter_(*this, NULL, 0), endConstIter_(*this, NULL, 0) { - for (label i=0; i>(Istream& is, HashTable& L) ) { is.putBack(lastToken); + Key key; is >> key; + T element; is >> element; + L.insert(key, element); is.fatalCheck @@ -174,8 +177,8 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const HashTable& L) // Write contents for ( - typename HashTable::const_iterator iter = L.begin(); - iter != L.end(); + typename HashTable::const_iterator iter = L.cbegin(); + iter != L.cend(); ++iter ) { diff --git a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.C b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.C index 3ba659c83d..7b011e135e 100644 --- a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.C +++ b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.C @@ -101,14 +101,17 @@ Foam::StaticHashTable::~StaticHashTable() template bool Foam::StaticHashTable::found(const Key& key) const { - label hashIdx = Hash()(key, keys_.size()); - const List& localKeys = keys_[hashIdx]; - - forAll(localKeys, elemIdx) + if (nElmts_) { - if (key == localKeys[elemIdx]) + label hashIdx = Hash()(key, keys_.size()); + const List& localKeys = keys_[hashIdx]; + + forAll(localKeys, elemIdx) { - return true; + if (key == localKeys[elemIdx]) + { + return true; + } } } @@ -131,14 +134,17 @@ Foam::StaticHashTable::find const Key& key ) { - label hashIdx = Hash()(key, keys_.size()); - const List& localKeys = keys_[hashIdx]; - - forAll(localKeys, elemIdx) + if (nElmts_) { - if (key == localKeys[elemIdx]) + label hashIdx = Hash()(key, keys_.size()); + const List& localKeys = keys_[hashIdx]; + + forAll(localKeys, elemIdx) { - return iterator(*this, hashIdx, elemIdx); + if (key == localKeys[elemIdx]) + { + return iterator(*this, hashIdx, elemIdx); + } } } diff --git a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableI.H b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableI.H index 5cd380357a..6ea55beae7 100644 --- a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableI.H +++ b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableI.H @@ -102,7 +102,7 @@ inline const T& Foam::StaticHashTable::operator[] { const_iterator iter = find(key); - if (iter == end()) + if (iter == cend()) { FatalErrorIn ( diff --git a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableIO.C b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableIO.C index 064ce3c619..766ccc9d64 100644 --- a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableIO.C +++ b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableIO.C @@ -33,7 +33,7 @@ License template Foam::StaticHashTable::StaticHashTable ( - Istream& is, + Istream& is, const label size ) : @@ -142,10 +142,13 @@ Foam::Istream& Foam::operator>>(Istream& is, StaticHashTable& L) ) { is.putBack(lastToken); + Key key; is >> key; + T element; is >> element; + L.insert(key, element); is.fatalCheck