Reputation: 217
I have this architecture(in short version):
class BaseBatch {
virtual ~BaseBatch(){};
};
template<class T>
class Batch : public BaseBatch
{
void draw(T* data) {
do something..
}
};
class BatchManager
{
private:
static std::vector<BaseBatch*> batches;
public:
template <class T>
static void placeData(T* data){
//Loop through the entire container
bool found = false;
for (auto&& b: batches())
if (b->get_type() == typeid(T)) {
dynamic_cast<Batch<T>*>(b)->draw(data);
found = true;
}
//If no bach found, create a new One
if (not found) {
batches.push_back(new Batch<T>);
}
}
};
Problem is that the placeData function is called multiple (many) times per 1 loop and I think that the dynamic casting is a real pain for the performance but cannot figure out how can I solve this without using it. Is it really that problematic or I shouldn´t bother with it and keep using it? If i should avoid it, what would you suggest? Thanks
Upvotes: 0
Views: 697
Reputation: 28178
Instead of using std::vector<Batch*>
use a std::unordered_map<std::type_index, std::unique_ptr<BaseBatch>>
. To access a batch use batches.find(std::type_index(typeid(T)))
, then static_cast
it to a Batch<T>*
. static_cast
has no runtime overhead. To create a new batch, use std::type_index(typeid(T))
as the key.
The performance of dynamic_cast
likely isn't the issue here. In fact, with this solution calling typeid
is likely just as bad as dynamic_cast
. The real potential gain is the lookup speed of the unordered_map
vs iterating through every element of a who-knows-how-big vector
and trying a dynamic_cast
.
Upvotes: 1