ECS?我实际上建议如果在设计的面向数据的方面投入大量的思想并基准化不同的代表可能还为时过早,因为它可能会影响您的界面设计,而后者在后期进行更改的成本很高。游戏。而且ECS只是需要大量的工作和前期的思考,我认为值得花一些时间来确保它不会给您带来设计级的性能困扰,因为这将成为您的核心整个怪胎引擎。这部分让我大吃一惊:
unordered_map<string,[yada]>
即使使用较小的字符串优化,也可以在另一个可变大小的容器(unordered_maps)内有一个可变大小的容器(字符串)。事实上,小串的优化实际上可能是有害的在这种情况下有益的,如果你的表是很稀疏,因为小串的优化将意味着哈希表的每一个未使用的指标仍然会使用更多的内存用于SS优化(sizeof(string)
会更大),以至于哈希表的总内存开销可能会比您存储在其中的开销更大,尤其是如果它是一个简单的组件(例如位置组件),并且由于步幅大而导致更多的缓存丢失从哈希表中的一个条目转到下一个条目。
我假设字符串是某种键,例如组件ID。如果是这样,这已经使事情大大便宜了:
unordered_map<int,[yada]>
...如果您希望拥有脚本编写者可以使用的用户友好名称的好处,例如,实习字符串可以为您提供两全其美的体验。
就是说,如果您可以将字符串映射到合理范围的密集使用的索引,那么您也许可以做到这一点:
vector<[yada]> // the index and key become one and the same
我不认为这种过早的原因是,它又可能会影响您的界面设计。DOD的目的不应该是尝试在一次IMO中提出可以想象得到的最有效的数据表示形式(通常应根据需要迭代实现),而应该对它们进行充分的考虑以设计顶部的接口以与之协同工作。数据为您留出了足够的喘息空间,可以进行分析和优化,而无需级联设计更改。
举一个朴素的例子,一个视频处理软件将所有代码与此相结合:
// Abstract pixel that could be concretely represented by
// RGB, BGR, RGBA, BGRA, 1-bit channels, 8-bit channels,
// 16-bit channels, 32-bit channels, grayscale, monochrome,
// etc. pixels.
class IPixel
{
public:
virtual ~IPixel() {}
...
};
是不会得到远没有潜在的史诗重写,因为在一个抽象的想法像素水平已经极其低效(的vptr
本身往往会成本比整个像素更多的内存)相比,在提取图像电平(这将通常代表数百万个像素)。因此,请事先对数据表示形式进行足够的考虑,以使您不必面对这样的噩梦场景,理想情况下也不必再面对这种情况,但是在这里,我确实值得对这些东西进行考虑,因为您不想构建一个您的ECS周围有复杂的引擎,发现ECS本身就是瓶颈,要求您在设计级别进行更改。
至于ECS缓存未命中,我认为开发人员经常会努力使ECS缓存友好。它开始产生的冲击力太小,以至于无法以完全连续的方式访问所有组件,并且通常意味着到处都在复制和改组数据。通常,只需要对基元索引进行基数排序就足够了,然后再访问它们,这样您就可以至少不将内存区域加载到高速缓存行中,仅逐出然后加载在同一循环中再次访问访问同一缓存行的不同部分。而且,ECS不必全盘提供惊人的效率。它不像物理系统或渲染系统那样能使输入系统受益,所以我建议目标是“好” 在您真正需要的地方全面提高效率并“出色”。也就是说,使用unordered_map
和string
这里有足够容易避免的。