std::map访问速度太慢
std::map Access Speed Is Too Slow?
我最近为我的游戏引擎实现了一个实体组件系统。每个实体都有这样的组件地图:
组件.h
enum COMPONENT_INFO {
COMPONENT_POSITION = 0,
COMPONENT_PHYSICS,
COMPONENT_RENDERABLE
};
实体.h
class Entity {
public:
std::bitset<NUM_COMPONENTS> componentBits;
std::map<COMPONENT_INFO, Component*> components;
..
..
Component *getComponent(COMPONENT_INFO inf) {
return components[inf];
}
};
我的System类每帧更新每个实体,如下所示:
void update(Entity *e, float delta) {
PositionComponent *cmp=(PositionComponent*)e->getComponent(COMPONENT_INFO::COMPONENT_PHYSICS);
//x += 1.0f;
cmp->x += 1.0f;
}
一切都按预期进行,但我在访问地图时遇到了巨大的性能问题。当我创建10000个实体并在其中迭代时(系统实际上在其中迭代),我得到了80 FPS的蓝色空白系统(没有视觉效果,只有纯屏幕)。但当我注释掉访问部分并只使用x += 1.0f;
时,FPS会逐渐增加到1000。比如:
void update(Entity *e, float delta) {
x += 1.0f; //btw the system has a local x value.
}
因此,问题仅在于通过映射访问组件。我还能在这样的系统上使用什么?或者我在访问地图时做错了什么?
重要编辑:这只是一个试驾,我的意思是每个实体可能有很多组件,而不仅仅是3个。我写这些只是为了测试。
由于每个实体的组件数量似乎是固定的,我会放弃映射,并使用entity中的成员变量来保存每个组件以及getter。这也将避免您的更新功能中的转换:
class Entity {
private:
PositionComponent* m_positionComponent;
PhysicsComponent* m_physicsComponent;
RenderableComponent* m_renderableComponent;
public:
// initialize the components in the constructor
PositionComponent* getPositionComponent() {
return m_positionComponent;
}
// more getters for the other components
}
或者,如果你想拥有更多的组件类型并保持设计的灵活性,你可能想将它们存储在一个向量中,使用枚举值对其进行索引。这将完全避免映射查找,并为你提供更好的性能。
由于COMPONENT_INFO
的最高数量是固定的,您可以使用array<Component*>
(或vector<>
,并使用例如myArray[COMPONENT_INFO::COMPONENT_PHYSICS]
进行寻址。不过,您可能必须检查nullptr。
首先,方法getComponent使用运算符[],它不仅检索具有给定键的实例,而且如果不存在,则插入一个元素。
http://www.cplusplus.com/reference/map/map/operator%5B%5D/
在给定的实现中,您将自己限制为实体中每种类型的一个组件,这可能不是最佳选择。例如,您可能希望为一个实体提供一些可渲染组件,以执行各种操作,如粒子、网格渲染等。
Map不能保证对象按顺序放置在内存中,这可能会在逐个处理时导致缓存未命中。例如,使用std::vector并将COMPONENT_INFO保留在组件对象本身中会更有效。
另一种解决方案是向系统类中添加方法,这些方法将创建特定类型的组件,在这样做的同时,对每个组件实例进行一些装订。然后,系统可以保留每种组件类型的矢量,并对这些矢量进行批处理。
希望这会有所帮助。
编辑:
其想法是,当您添加/创建新的碰撞组件时,组件本身会在系统中注册,提供类型和指向自身的指针。渲染图也是如此。您可以为系统中的每个组件类型提供矢量映射。当你需要解决collsion时,你只需要检索所有的collidables(对向量的引用)。您进行一次查找,即log(n),然后在所有collidables上迭代(由于位于向量中,指针在内存中按顺序排列,使其对缓存更友好)。
您还测试发布版本中的性能吗?
- 并发内存访问减慢系统速度
- 访问静态和堆内存的速度
- 访问std::vector元素的速度会随着向量大小而减慢
- 访问对象的变量会减慢程序速度 (C++)
- 封装的二维数组与普通版本相比——访问速度
- 通过索引访问矢量的速度:向后与向前
- C++加快地图访问速度
- 访问堆栈变量的速度比取消引用指针慢
- 以尽可能快的速度访问数百个文件
- c++是否有一个默认的数据类,用于以合理的速度对基于索引的访问进行排序
- std::map访问速度太慢
- 加快C++堆内存访问的速度
- 矢量访问速度,哪种方法更快
- 特征:访问矩阵4列的速度很慢
- c/c++中访问const变量的速度
- c++ XML解析器(速度,访问DOM树)
- 与普通数组相比,内存访问向量的速度有多快
- 在不同优化级别访问gcc/g++中的局部变量与全局变量的速度
- c++中访问原子变量的速度有多快?
- 平衡文件空间,内存访问和写入速度的结构数组到文件