Sto provando ad implementare un'architettura basata su componenti in un progetto di motore di gioco. Ogni GameObject ha uno unordered_map
che contiene un puntatore alla classe base Component
. A questo punto, ho solo una classe derivata da un componente, che è la classe Transform
. Volevo implementare questa architettura basata su componenti simile alla convenzione di Unity: voglio ottenere un componente dell'oggetto di gioco chiamando la funzione template membro come GetComponent<Transform>()
.Basso rendimento da unordered_map quando si accede agli elementi nella funzione modello membro nella classe derivata
Ecco le intestazioni:
Component.h
enum type{
TRANSFORM // more will be added later
};
class Component // base class
{
public:
Component() : _owner(NULL) {}
virtual ~Component(){}
static type Type;
protected:
GameObject* _owner;
};
Transform.h
class Transform : public Component
{
public:
Transform();
~Transform();
static type Type;
void Rotate(float deg);
// to be encapsulated later on
Vector2D _position;
float _rotation;
Vector2D _scale;
};
GameObject.h
class GameObject
{
public:
GameObject();
~GameObject();
void Update();
//and more member functions
template<class T>
T* GetComponent();
private:
// some more private members
unordered_map<type, Component*> _componentList; // only 1 component of each type
};
template<class T>
T* GameObject::GetComponent()
{
return static_cast<T*>(_componentList[T::Type]);
}
mio implementazione iniziale utilizzato std::vector
per mantenere Component*
e l'applicazione corse a 60 fps (ho anche un controllore frame rate, che limita solo la FPS a 60). Quando sono passato a unordered_map
per accedere a quei puntatori di componenti, le prestazioni sono ridotte a 15 FPS.
I disegnare solo due quad e invito GetComponent<Transform>()
solo 6 volte al telaio a questo punto, quindi non v'è molto movimento nella scena.
Cosa ho provato?
Ho cercato di usare const char*
, std::string
, type_info
e infine enum type
come valori fondamentali per il unordered_map
ma niente aiuta davvero: tutte le implementazioni mi ha fatto 15-16 FPS.
Quali sono le cause di questo problema di prestazioni? Come posso isolare il problema?
spero che ho fornito sufficienti dettagli, non esitate a chiedere di più il codice, se necessario
Le entità di solito hanno solo pochi componenti, forse 5 o al massimo 30. Per 30 elementi un vettore con ricerca lineare supera una hash_map. Vorrei limitarmi ai vettori. – nwp
Non so nulla della programmazione del gioco, ma non potresti istanziare un array di puntatori con sempre elementi num_components? I valori del tipo enum possono essere espressi come indici nell'array e, se si dispone di pochi componenti, potrebbe non trattarsi di un sovraccarico di memoria elevato – dgel
cos'altro è stato modificato? Non credo che * solo * abbia cambiato il contenitore dei tuoi componenti. calcolare un valore di hash è banale. inferiore al costo di invio delle istruzioni di disegno a una GPU. –