Ich versuche, eine komponentenbasierte Architektur in einem Game-Engine-Projekt zu implementieren. Jedes GameObject hat einen unordered_map
, der einen Zeiger auf die Basisklasse Component
enthält. An diesem Punkt habe ich nur eine Komponente abgeleitet Klasse, die Transform
Klasse ist. Ich wollte diese komponentenbasierte Architektur ähnlich der Unity-Konvention implementieren: Ich möchte eine Komponente des Spielobjekts erhalten, indem ich die Elementvorlagenfunktion wie GetComponent<Transform>()
aufruft.Niedrige Leistung von unordered_map beim Zugriff auf Elemente in Member Template-Funktion in abgeleiteten Klasse
Hier sind die Header:
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]);
}
Meine anfängliche Implementierung verwendete std::vector
für Component*
zu halten und die Anwendung lief bei 60 fps (Ich habe auch einen Frame-Rate-Controller, der nur die FPS auf 60 begrenzt). Als ich zum Zugriff auf diese Komponentenzeiger auf unordered_map
wechselte, ging die Leistung auf 15 FPS herunter.
Ich zeichne nur zwei Quads und ich rufe GetComponent<Transform>()
nur 6-mal pro Rahmen an dieser Stelle, so ist es nicht viel in der Szene geht.
Was habe ich versucht?
Ich habe versucht, für die unordered_map
const char*
, std::string
, type_info
und schließlich enum type
als Schlüsselwerte zu verwenden, aber nichts wirklich hilft: alle Implementierungen hat mich 15-16 FPS.
Was verursacht dieses Leistungsproblem? Wie kann ich das Problem isolieren?
Ich hoffe, dass ich genug Detail zur Verfügung gestellt, können Sie für mehr Code zu fragen, wenn nötig
Entitäten haben normalerweise nur wenige Komponenten, vielleicht 5 oder höchstens 30. Für 30 Elemente übertrifft ein Vektor mit linearer Suche eine hash_map. Ich würde einfach bei Vektoren bleiben. – nwp
Ich weiß nichts über die Programmierung von Spielen, aber konnten Sie nicht ein Zeigerarray mit immer num_components Elementen instanziieren? Die Typ-Enum-Werte können als Indizes in das Array umgewandelt werden, und wenn Sie wenige Komponenten haben, ist dies möglicherweise kein hoher Speicher-Overhead. – dgel
Was haben Sie sonst noch geändert? Ich glaube nicht, dass Sie * nur * den Speicherbehälter Ihrer Komponenten verändert haben. Einen Hashwert zu berechnen ist trivial. niedriger als die Kosten für das Senden von Zeichenanweisungen an eine GPU. –