mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
HashTbl avoid backward search in erase()
- The ideas as discussed in email - The speedup is really there. Before loop 0 - Erased 100000 elements: 3.82 s loop 1 - Erased 100000 elements: 11.45 s loop 2 - Erased 100000 elements: 19.46 s loop 3 - Erased 100000 elements: 27.73 s loop 4 - Erased 100000 elements: 38.74 s ^C After loop 0 - Erased 100000 elements (size 2900000 capacity 8388608) 0.01 s loop 1 - Erased 100000 elements (size 2800000 capacity 8388608) 0 s loop 2 - Erased 100000 elements (size 2700000 capacity 8388608) 0.01 s loop 3 - Erased 100000 elements (size 2600000 capacity 8388608) 0 s loop 4 - Erased 100000 elements (size 2500000 capacity 8388608) 0 s loop 5 - Erased 100000 elements (size 2400000 capacity 8388608) 0 s loop 6 - Erased 100000 elements (size 2300000 capacity 8388608) 0 s loop 7 - Erased 100000 elements (size 2200000 capacity 8388608) 0 s ...
This commit is contained in:
@ -56,15 +56,16 @@ int main(int argc, char *argv[])
|
|||||||
HashTbl<label, label, Hash<label> > map(2 * nSize);
|
HashTbl<label, label, Hash<label> > map(2 * nSize);
|
||||||
|
|
||||||
Info<< "Constructed map of size: " << nSize
|
Info<< "Constructed map of size: " << nSize
|
||||||
|
<< " (size " << map.size() << " capacity " << map.capacity() << ") "
|
||||||
<< " " << timer.cpuTimeIncrement() << " s\n\n";
|
<< " " << timer.cpuTimeIncrement() << " s\n\n";
|
||||||
|
|
||||||
for (label i = 0; i < nSize; i++)
|
for (label i = 0; i < nSize; i++)
|
||||||
{
|
{
|
||||||
map.insert(i, i);
|
map.insert(i, i);
|
||||||
}
|
}
|
||||||
Info<< "Inserted " << nSize << " elements: "
|
Info<< "Inserted " << nSize << " elements"
|
||||||
<< timer.cpuTimeIncrement() << " s\n\n";
|
<< " (size " << map.size() << " capacity " << map.capacity() << ") "
|
||||||
|
<< timer.cpuTimeIncrement() << " s\n";
|
||||||
|
|
||||||
label elemI = 0;
|
label elemI = 0;
|
||||||
for (label iLoop = 0; iLoop < nLoops; iLoop++)
|
for (label iLoop = 0; iLoop < nLoops; iLoop++)
|
||||||
@ -73,8 +74,9 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
map.erase(elemI++);
|
map.erase(elemI++);
|
||||||
}
|
}
|
||||||
Info<< "loop " << iLoop << " - Erased " << nBase << " elements: "
|
Info<< "loop " << iLoop << " - Erased " << nBase << " elements"
|
||||||
<< " " << timer.cpuTimeIncrement() << " s\n";
|
<< " (size " << map.size() << " capacity " << map.capacity() << ") "
|
||||||
|
<< timer.cpuTimeIncrement() << " s\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -346,55 +346,41 @@ bool Foam::HashTbl<T, Key, Hash>::erase(const iterator& cit)
|
|||||||
{
|
{
|
||||||
if (cit.elmtPtr_) // note: endIter_ also has 0 elmtPtr_
|
if (cit.elmtPtr_) // note: endIter_ also has 0 elmtPtr_
|
||||||
{
|
{
|
||||||
iterator& it = const_cast<iterator&>(cit);
|
|
||||||
|
|
||||||
// Search element before elmtPtr_
|
// Search element before elmtPtr_
|
||||||
hashedEntry* prev = 0;
|
hashedEntry* prev = 0;
|
||||||
|
|
||||||
for (hashedEntry* ep = table_[it.hashIndex_]; ep; ep = ep->next_)
|
for (hashedEntry* ep = table_[cit.hashIndex_]; ep; ep = ep->next_)
|
||||||
{
|
{
|
||||||
if (ep == it.elmtPtr_)
|
if (ep == cit.elmtPtr_)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
prev = ep;
|
prev = ep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// adjust iterator after erase
|
||||||
|
iterator& iter = const_cast<iterator&>(cit);
|
||||||
|
|
||||||
if (prev)
|
if (prev)
|
||||||
{
|
{
|
||||||
// Have element before elmtPtr
|
// has an element before elmtPtr - reposition to there
|
||||||
prev->next_ = it.elmtPtr_->next_;
|
prev->next_ = iter.elmtPtr_->next_;
|
||||||
delete it.elmtPtr_;
|
delete iter.elmtPtr_;
|
||||||
it.elmtPtr_ = prev;
|
iter.elmtPtr_ = prev;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// elmtPtr is first element on SLList
|
// elmtPtr was first element on SLList
|
||||||
table_[it.hashIndex_] = it.elmtPtr_->next_;
|
table_[iter.hashIndex_] = iter.elmtPtr_->next_;
|
||||||
delete it.elmtPtr_;
|
delete iter.elmtPtr_;
|
||||||
|
|
||||||
// Search back for previous non-zero table entry
|
// assign an non-NULL value so it doesn't look like end()/cend()
|
||||||
while (--it.hashIndex_ >= 0 && !table_[it.hashIndex_])
|
iter.elmtPtr_ = reinterpret_cast<hashedEntry*>(this);
|
||||||
{}
|
|
||||||
|
|
||||||
if (it.hashIndex_ >= 0)
|
// mark with special hashIndex value
|
||||||
{
|
// to signal that it has been rewound
|
||||||
// In table entry search for last element
|
// the next increment will bring it bach to the present location
|
||||||
it.elmtPtr_ = table_[it.hashIndex_];
|
iter.hashIndex_ = -iter.hashIndex_ - 1;
|
||||||
|
|
||||||
while (it.elmtPtr_ && it.elmtPtr_->next_)
|
|
||||||
{
|
|
||||||
it.elmtPtr_ = it.elmtPtr_->next_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// No previous found. Mark with special value which is
|
|
||||||
// - not end()/cend()
|
|
||||||
// - handled by operator++
|
|
||||||
it.elmtPtr_ = reinterpret_cast<hashedEntry*>(this);
|
|
||||||
it.hashIndex_ = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nElmts_--;
|
nElmts_--;
|
||||||
@ -402,8 +388,8 @@ bool Foam::HashTbl<T, Key, Hash>::erase(const iterator& cit)
|
|||||||
# ifdef FULLDEBUG
|
# ifdef FULLDEBUG
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Info<< "HashTbl<T, Key, Hash>::erase(iterator&) : "
|
Info<< "HashTbl<T, Key, Hash>::erase(const iterator&) : "
|
||||||
<< "hashedEntry " << it.elmtPtr_->key_ << " removed.\n";
|
<< "hashedEntry " << iter.elmtPtr_->key_ << " removed.\n";
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
|||||||
@ -178,6 +178,9 @@ public:
|
|||||||
|
|
||||||
// Access
|
// Access
|
||||||
|
|
||||||
|
//- The size of the underlying table
|
||||||
|
inline label capacity() const;
|
||||||
|
|
||||||
//- Return number of elements in table.
|
//- Return number of elements in table.
|
||||||
inline label size() const;
|
inline label size() const;
|
||||||
|
|
||||||
|
|||||||
@ -55,6 +55,13 @@ Foam::HashTbl<T, Key, Hash>::hashKeyIndex(const Key& key) const
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class T, class Key, class Hash>
|
||||||
|
inline Foam::label Foam::HashTbl<T, Key, Hash>::capacity() const
|
||||||
|
{
|
||||||
|
return tableSize_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T, class Key, class Hash>
|
template<class T, class Key, class Hash>
|
||||||
inline Foam::label Foam::HashTbl<T, Key, Hash>::size() const
|
inline Foam::label Foam::HashTbl<T, Key, Hash>::size() const
|
||||||
{
|
{
|
||||||
@ -256,16 +263,17 @@ inline
|
|||||||
typename Foam::HashTbl<T, Key, Hash>::iterator&
|
typename Foam::HashTbl<T, Key, Hash>::iterator&
|
||||||
Foam::HashTbl<T, Key, Hash>::iterator::operator++()
|
Foam::HashTbl<T, Key, Hash>::iterator::operator++()
|
||||||
{
|
{
|
||||||
// Check for special value from erase. (sets hashIndex to -1)
|
// Check for special value (from erase) - this indicates the previous bin
|
||||||
if (hashIndex_ >= 0)
|
if (hashIndex_ < 0)
|
||||||
|
{
|
||||||
|
hashIndex_ = -hashIndex_;
|
||||||
|
}
|
||||||
|
else if (elmtPtr_ && elmtPtr_->next_)
|
||||||
{
|
{
|
||||||
// Do we have additional elements on the SLList?
|
// Do we have additional elements on the SLList?
|
||||||
if (elmtPtr_ && elmtPtr_->next_)
|
|
||||||
{
|
|
||||||
elmtPtr_ = elmtPtr_->next_;
|
elmtPtr_ = elmtPtr_->next_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Step to the next table entry
|
// Step to the next table entry
|
||||||
while
|
while
|
||||||
@ -275,9 +283,9 @@ Foam::HashTbl<T, Key, Hash>::iterator::operator++()
|
|||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
if (hashIndex_ == hashTable_.tableSize_)
|
if (hashIndex_ >= hashTable_.tableSize_)
|
||||||
{
|
{
|
||||||
// make end iterator
|
// make an end iterator
|
||||||
elmtPtr_ = 0;
|
elmtPtr_ = 0;
|
||||||
hashIndex_ = 0;
|
hashIndex_ = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user