Reputation: 4452
I have a std::vector<MyClass*>
(a vector of MyClass pointers), and I need to find a particular item in the vector. The class has a getID()
function which returns a unique identifier of the class.
If I want to find a class with a specific ID, I iterate through the vector looking for the class with the ID, like this:
for(std::vector<Chunk*>::iterator it = chunksRenderList.begin(); it != chunksRenderList.end(); ++it)
{
if((*it)->getID() == id)
return *it;
}
This is rather slow because I am calling this code lots of times per second. I have tried using a std::unordered_map
which was a lot slower, and a std::map
was slower again. I'm not sure why it was slower, maybe it's the way I used it.
Is there any container/algorithm I can use to access a particular item without having to iterate (that is faster than iteration)?
Upvotes: 1
Views: 679
Reputation: 24946
If your container is sorted accoding to the value of getID() you may try using a binary search.
class A
{
size_t m_id;
public:
A (size_t id) : m_id(id) {}
size_t getID (void) const { return m_id; }
};
template<class T1, class T2>
struct less_id
{
bool operator () (T1 const &lhs, T2 const & cmp)
{
return (lhs->getID() < cmp);
}
};
int main (void)
{
std::vector<A*> v;
v.push_back(new A(2));
v.push_back(new A(3));
v.push_back(new A(4));
v.push_back(new A(5));
less_id<A*, size_t> cmp;
size_t find_value = 4;
std::vector<A*>::iterator found = std::lower_bound(v.begin(), v.end(), find_value, cmp);
if(found == v.end() || !((*found)->getID() == find_value))
{
// not found
}
else
{
// found
std::cout << "Found element: " << (found-v.begin()) << std::endl;
}
for (size_t i=0; i<v.size(); ++i) delete v[i];
v.clear();
}
Shows
Found element: 2
Where A
== Chunk
and v
== chunksRenderList
.
Upvotes: 3
Reputation: 490168
If you're doing this enough to justify it, the obvious thing to do would be to sort the vector, then use a binary search to find your item.
If your ID's are reasonably predictably distributed over the range they cover, you could use an interpolating search to reduce the complexity from O(N) to roughly O(log log N) -- though it has enough higher constant that it's generally only a win with a fairly large collection.
Upvotes: 2