我浏览了虚幻引擎源代码,发现它们使用自己的容器类,例如内部动态数组。但是 C++ STL 提供了(几乎)所有需要的容器类。那么他们为什么要花时间再次开发相同的容器呢?对于开发人员来说,使用
std::vector
等容器来编写代码,而不是尝试弄清楚如何使用引擎中的 TArray
类来完成任务,不是更容易吗?
项目可能不使用 STL 容器的原因有多种:
项目中使用的容器是量身定制的,具有与STL版本不同的某些性能特征。
当设计自定义容器时,STL 容器甚至可能还不存在,并且不值得对工作项目进行如此大的更改。
虽然大多数开发人员都习惯了 STL 容器,但特定项目的大多数贡献者实际上可能更习惯自定义版本以及如何使用它们,并且重新培训所有这些容器可能也不值得。
对于任何特定项目,上述部分或全部,甚至其他原因可能会导致决定使用自定义容器。
除了@cigien提到的原因之外 - 即使此类应用程序的开发人员不需要定制的容器,但几个标准库容器仍然非常慢,例如:
因为游戏和其他桌面/服务器应用程序之间的数据模式和运行模式非常不同。
游戏的数据主要来自于预先打包的资源,因此数据的大小和结构对于引擎来说很大程度上是已知的,引擎可以预先分配一大块内存来一次性加载所有数据,或者足够大的内存块可以连续流式传输内容,因此重写自己的容器或分配器将带来很大的性能增益并降低内存管理的复杂性,这是非常值得的。
在桌面/服务器应用程序中,数据通常来自应用程序外部,因此大小和结构通常是未知或不可预测的,想象一下您在 Premium 中打开了一个非常大的视频编辑项目,或者在 Chrome 中打开了 100 个选项卡,或者突然由于营销促销,10 万用户涌入您的 Web 服务器,该软件必须考虑内存使用量的突然变化。
另一个区别是跑步模式。游戏通常是独占运行的,玩家在玩游戏时不会执行多任务(我猜除了在 Twitch 上直播时),因此游戏可以尽可能地获取所有 CPU/RAM 资源并尽可能快地运行。但桌面/服务器应用程序通常需要与其他应用程序共存和多任务,它们应该只为当前负载分配足够的内存。
STL中的容器类主要针对最常见的场景而设计,这些场景使用尽可能少的内存并随负载扩展,因此它们不适合直接在游戏引擎中用于性能关键数据。