每种编程语言都有其标准的容器,算法和其他有用的库。对于C#,Java和Python之类的语言,使用没有标准库的语言实际上是不可想象的。
但是,在我从事过的许多C ++游戏中,我们要么根本不使用STL,要么只使用其中的一小部分,要么使用我们自己的实现。很难说这对我们的游戏是一个明智的决定,还是仅仅由于对STL的无知而做出的决定。
那么... STL是否合适?
每种编程语言都有其标准的容器,算法和其他有用的库。对于C#,Java和Python之类的语言,使用没有标准库的语言实际上是不可想象的。
但是,在我从事过的许多C ++游戏中,我们要么根本不使用STL,要么只使用其中的一小部分,要么使用我们自己的实现。很难说这对我们的游戏是一个明智的决定,还是仅仅由于对STL的无知而做出的决定。
那么... STL是否合适?
Answers:
早在我从事专业游戏开发工作时,STL太不成熟,而且肿。但这是在10年前。
现在,我从事军事模拟工作,这对性能有更严格的要求(例如帧速率永远不能低于某些FPS)。在军事模拟中,STL被广泛使用。
有些告诉您不要使用STL的人使用这样的论点,即它并不总是解决问题的完美甚至最佳的解决方案。但这不是问题的答案。问题应该是:在游戏中使用STL有天生的错误吗?我会说不,STL在大多数情况下是比用户自己想出的更好的实现。
只要确保您知道如何使用STL,然后在游戏中使用它即可。阅读一些书籍,并查看正在使用的STL中的实现代码。
if(stream.nextCharacter() == '#') stream.skipLine();
我想说的是,最好还是使用STL,除非您确切知道为什么不使用它。
关于STL的事情是这样的:它是由比您聪明的人开发的。这不是冒犯性的,也不是任何东西,仅仅是STL是由实际正在构建STL的人员开发的。它将在平台允许的范围内达到几乎最快的速度,并且通常比家用解决方案要健壮得多(如果您不担心原始速度,那么这将是一个令人担忧的问题,因为您的游戏需要健壮性比您需要的速度要好得多;没有前者,后者就毫无意义。
关于STL实施“世界观”的抱怨让我感到有些愚蠢。他们是容器。它们的操作集有限,因为容器的操作集有限。您正在做什么,这不符合您的意愿?
我发现很少有理由不将STL用于游戏。
对于内存分配问题,很多人都不知道,但是您可以为STL容器类编写自定义分配器。分配器基本上是您传递到模板中的策略类,以确定如何执行分配。使用这些功能,通常可以解决所选平台上出现问题的任何内存问题。
当然,如果您正在使用STL并做一些愚蠢的事情,例如将字符串映射映射为大的非指针类型,那么您手头上会遇到更大的问题。
google::sparse_map
或编写自己的游戏。
默认的STL有很多问题,使游戏难以使用,尤其是在内存对齐方面。
定制的变体(例如EA STL)是专门为游戏设计的,可以为您提供更好的内存性能和控制台可用性。根据BSD-3条款,它于2016年成为开源,并在GitHub上有一个存储库。
std::vector
,覆盖了默认分配器。
这是迈克·阿克顿(Mike Acton)(在《龙,棘轮与叮当》和《抵抗》声望很高的斯波罗(Spyro)失眠游戏的引擎总监)在这里被问到的话。请注意,通常询问他有关STL和Boost的信息,这些信息与游戏开发人员的用法有关。
STL / Boost,它属于gamedev吗?如果只是一部分,那是哪一部分?
您在这里问两件事,对吗?STL和Boost分别。但实际上,我的答案是相同的:两者本身都没有错,但我不鼓励使用它们。任使用鼓励人们适合解决一个问题,而不是寻找一个解决问题的办法。该解决方案应始终适合于手头的数据以及硬件的限制等。STL和Boost都对“世界”有极其狭窄的了解,并且它们的适当使用受到限制。的确,我不鼓励他们,因为它们会立即导致程序员走错方向,我经常说,如果您觉得自己需要一个,那您可能根本就不了解自己的问题。
我还注意到,大多数职业游戏开发人员在C语言上的努力要超过C ++。
如果发现由于某种原因重写了STL中已经存在的内容,请停止。使用STL。
经过多年的分析和时间,对STL进行了优化,可以肯定的是,您可能不会编写更有效的内容。这并不是说您应该在可能有更简单解决方案的地方使用STL(例如,在已知数量的东西而不是stl :: list的情况下使用数组),但是如果您正在编写自己的地图实现(基本数据结构,而不是游戏世界地图),您做错了。
std::sort
通常在下面使用introsort,其速度非常快而且非常复杂,以至于您不想自己做。
unordered_map
C ++ 11或boost都太慢了,您想要的是开放地址哈希映射,例如google :: sparse_map或您自己的。
我知道这对聚会来说很晚,但是时间变化和答案仍然存在。C ++ 11进行了相当大的更改,其中许多更改都是为了提高C ++和标准库的性能。似乎那些不使用STL或Boost的人也往往不会跟上新标准,使得家用旋转解决方案缺乏重要的改进,当然,并非总是如此。
从90年代中期到今天,我在每个项目中都使用了STL,但在EA的时间很短。我认为反STL方面有一些不使用它的理性原因。这些基本上消失了。自定义分配器是一种解决方案,使用保留是另一种解决方案,不按值传递是第三种解决方案,但是这些非常简单,任何程序员都应该知道这些。不过,更重要的是算法的使用。编译器作者确切知道for_each()的功能,并且可以优化代码。本地循环不会发生这种情况。const对象上的for_each()甚至更好。Microsoft通过多种方法对for_each进行了优化,包括序列化。它们还具有带有parallel_for_each()的AMP库。如果有机会,请与编译器工程师联系。控制台编译器将优化使用的内容,因此 有点鸡鸡蛋问题。微软对C ++ 11的投入非常大,下一个XBox也不例外。我不知道PS4,我们还没有得到。
自定义分配器是处理内存问题的一种方法,但另一种(通常被忽略)的方法是使用基于类的new和delete。这样可以极大地提高性能。
Boost和STL对解决问题的看法很狭窄,这是纯粹的精神错乱。我对通过特性和策略可以自定义STL和Boost中的多少感到惊讶。以不区分大小写的字符串比较为例。
关于较长的链接时间和代码膨胀,新的extern模板应对此有所帮助。通常,我发现较长的编译时间来自过多的耦合和对pch的滥用。
在本地使用STL的最有说服力的理由是,有数百万人可以帮助您使用STL。与往常一样,不要过早优化和测试,测试,测试。
这是游戏开发中的热门话题。除了上面提到的EASTL,我个人不建议这样做。我在游戏中遇到了STL的两个主要问题(从技术上讲是“ C ++标准库”,因为STL不再是名称)。1)使用STL时,动态内存分配通常会浪费大量游戏时间。2)STL的使用鼓励了游戏架构的结构数组方法,而数组结构方法则更易于缓存。
这取决于。项目有多大,平台多少个,时间表如何?
如果您在一个大型项目上,在资源有限的平台上,有大量的时间和预算,那么您可以避免不可避免的地狱,这将使您陷入半百万行代码库的麻烦之中,从而为您节省很多麻烦STL杂乱无章,无法将帧速率保持在30以上,吃掉了足够的RAM来容纳更多资产,并且需要2个小时来构建。
但是,在其他情况下,如果正确应用STL甚至Boost也会非常有用。我从事过使用STL / Boost的选择的工作,并且绝对是编写代码的梦想:更少的错误/泄漏和易于维护的代码意味着更多的时间编写有趣的新功能!特别是对于业余项目,这是动力部门的一项巨大胜利。
知道何时换性能以方便使用!
恕我直言,我说这很合适,因为STL已经很好地工作了,并且针对其完成的任务进行了优化。此外,您正在开发游戏,因此,请使用手边的工具,这些工具可以使您的生活更轻松,并且代码不易出现错误。
当您可以从事游戏的AI,用户体验或其他更好的工作时,为什么还要重新设计轮子呢?测试和调试?
只要您了解STL,就可以在游戏中使用它。我们的引擎对其进行了广泛的使用,这从来都不是问题。我没有控制台开发方面的经验,这可能是一个完全不同的故事,但是在所有PC平台(Windows / Mac / Linux)上都很好地支持了它。
最重要的是要了解每种容器类型的优点和缺点,并为您要执行的工作选择正确的容器。
好问题!一个更具体的问题是,使用STL和Boost无法满足游戏的一些常见要求。
以我的经验,控制台硬件的严格内存限制使任何类型的动态大小的容器都不是一个好主意,无论您的自定义分配器多么聪明。没有故意界限的容器鼓励程序员编写不限制其数据集界限的代码。根据难以跟踪的无数变量,您可能会超出内存限制。我直觉这是现代游戏不稳定的主要原因之一。
此外,模板的过度使用会导致大量代码库中的编译时间很长,并且会膨胀可执行文件的大小,从而使其不再适合ps3上辅助内核的缓存。
但是,对于仅PC的开发,我认为STL和Boost非常好。尽管一般情况下的解决方案并不总是理想的,但它们通常足够好。您对问题的第一个解决方案几乎从来都不是理想的,并且您需要改进或替换不足之处,直到足够好为止。
如果STL非常适合您的游戏,则STL非常适合您的游戏。
与在开发过程中做出的所有技术选择一样,您需要权衡利弊–滚动我自己的库会比仅仅使用STL给我更多有益的内存使用,性能和生产率吗?可能 vector
与使用现有内存相比,创建使用更多内存,速度较慢并且需要大量维护才能保持功能的实现同样容易。
人们不应该避免在游戏中使用STL,因为其他人可以避免在游戏中使用STL。如果他们权衡了所有选项,他们应该避免使用它,并且他们真正相信另一种实现方式将提高其产品的质量。
vector
比STL的人做得更好。到您可以做到时,您不再认为需要这样做!:-)
我认为讨论可以总结如下:
平庸的应用专用代码<良好的通用代码<良好的应用专用代码
自行开发的解决方案将属于第3类的任何人都肯定知道他们特定问题的原始问题的答案。STL属于类别2。因此,对于需要提出“ 我应该使用STL”这个问题的人,答案可能是肯定的。
STL可以在PC上使用,因为它的高级虚拟内存系统使谨慎分配内存的需求变得不那么紧要了(尽管仍然必须非常小心)。在虚拟内存设备有限或没有虚拟设备且缓存未命中成本高昂的控制台上,您可能最好编写具有可预测和/或有限内存分配模式的自定义数据结构。(而且在PC游戏项目上做同样的事情当然也不会错。)
我认为这个问题确实是一个更大的未决问题-我应该在Y中使用X吗?真正答案的唯一方法是亲自尝试一下。对于发现X很棒的每个人,您都会发现有人说X太可怕了。他们两个都是正确的-对于他们的项目。
与大多数其他学科不同,软件的伟大之处在于,如果发现软件没有按照您希望的方式工作,您以后可以随时进行更改。稍后您会发现STL在该项目中不适合您吗?撕掉它,放在其他地方。不喜欢您如何在对象之间划分职责?重构。不喜欢使用物体吗?用直接的C方法替换它们。不喜欢将所有内容存储在结构和方法中以对其进行操作吗?用C ++对象替换它们。
我对STL表示反对。我的原因很简单:
我认为迭代计数是最重要的,所以我只是避免使用STL和其他任何会减慢迭代速度的开发技术(例如,出于这种原因而进行架构设计,或需要编译的脚本语言)。
代价高昂的迭代会导致庞大的开发团队尝试在几乎没有实际发生的情况下完成工作。我已经看过并听到了,罪魁祸首之一似乎是模板库的编译时间。