在C ++开发中放弃STL是否可行?[关闭]


19

我知道在某些领域(例如游戏行业),不建议使用STL。所以我的问题是:在某些情况下不使用STL是否真的是一个好习惯?如果是这样,不使用现代C ++的STL的最大原因是什么?



我的一些同事认为,迭代器使调试更加困难,因为有时步入并不容易,这也适用于lambda。您对此有何反应?
CaptainJH 2012年

至于调试过程中跳过的东西,看到的,例如:stackoverflow.com/questions/2062881/...
马丁巴

这似乎是一个好问题。也许有人可以添加“为什么项目会选择不使用STL?”
马修·詹姆斯·布里格斯

Answers:


25
  • 我只能想到一个正当的理由,这真的很罕见:实时性很差。标准库中的许多内容都是在内部分配内存的,对于硬实时应用程序而言,这还不够确定,因此必须避免。这些应用程序通常非常简单,但是由于非常严格的审查和测试,它们花费了不成比例的时间来开发。

  • 我可以想到一个无效但很常见的原因:不了解计算复杂性的开发人员会滥用STL,然后将其归咎于库。

    STL在运行时通常比具有回调指针的C样式解决方案或具有虚拟方法的基于多态的解决方案要快(另请参见此Bjarne Stroustrup的主题演讲)。但是,当开发人员不理解给出的复杂性规范,并通过创建某些复杂对象的向量vector之类的东西来滥用库时(在C ++ 11中,这不再是问题!),会导致性能问题,并且无法保护自己如果您看到“向量很慢”,则可能会导致人们认为标准库很慢。经理一旦有了这种认识,就可以在组织中生存很长时间。

  • 显然,您不能使用目标平台不支持的任何功能。但是,我们目前的目标是四个最常见的移动平台(Android,iOS,Bada和旧的WinCE),并在所有平台上使用标准库和Boost的某些部分。

    Microsoft在WinCE早期就不支持许多标准库(IIRC iostream仅随Visual Studio 2005一起提供),但是有可能在此之前使用STLport很久了。通常,您可以将其编译为任何东西。因此,我也将这个原因称为无效。

    此外,长期以来,它不是“ STL”,而是ANSI C ++标准库。它是由定义语言本身的同一标准文档定义的。任何不支持它的东西都不应该真正被称为C ++。


6
第一个参数(实时)并不特定于标准库的STL部分。sprintf经常也会分配内存。在实时平台上,标准库函数也具有确定性限制。这使实时C ++实现变得很困难:您必须仔细开发整个C ++标准库,这比小型C标准库要花更多的精力。
MSalters 2012年

@MSalters:当然,很多事情不能在实时要求下使用。甚至某些语言功能(如异常)也无法实现。对于这些系统,C ++仍然是很棒的语言,因为它可以将性能和精确控制与强大的保障结合在一起(RAII是最重要的功能)。
Jan Hudec 2012年

@JanHudec:确实,这就是为什么仅STL部分才是C ++的“托管”实现所必需的。
MSalters

7

我使用STL并提升了很多年。如果我想放弃它并使用我的自定义工具,其动机将是:

  1. 减少编译时间(75%)。仅包含iostream即可向模块添加一百万行代码。是的,预编译的头文件有很大帮助,但是在大型项目中,它仍然使编译速度大大降低。从长远来看,这样做会浪费很多时间在工作上。
  2. 性能。(25%)STL通常可以正常工作,但是您可以优化结构以完全按照需要工作。例如,您可能有一个包含数百万个短字符串的数据结构。使用基于boost :: small_vector原理的自定义字符串类可能要快得多(基于数据的静态小局部矢量,仅对较大的字符串进行动态分配),这些更改可以使关键代码段的工作速度提高许多倍。

1
SSO已经很常见。
Deduplicator

对于后代:SSO->小字符串优化,即大多数(全部?)std :: string实现将小字符串保留在堆栈上,并在需要时切换到堆
蓝色

编译时间很重要
user1754322

4

没有使用C ++标准模板库的一个很大的正当理由:您的目标平台之一没有完全符合要求的实现(或者根本没有实现),并且您知道它不会得到一个在未来几年内。


3
也就是“没有时不要使用它”,这确实是有道理的。:)
Xeo

4
鉴于C ++ 03标准库仅设计为仅根据ANSI C89库实现,是否有任何平台至少不能提供STLPort
Jan Hudec 2012年

@JanHudec我相信有些平台没有STL,因为它们没有足够的内存来处理整个事情。通常,他们还缺少其他一些C ++功能(例如,异常)。
苏珊(Sulthan)2012年

2
@Sulthan:对于微控制器我有点理解,但是通常属于“硬实时”类别。对于其他任何事情,这大多是先入为主的,因为STL通常在内存和性能方面都与手工编写的代码一样高效。大量内联可能会导致较大的二进制文件,但是甚至可以通过以某些性能成本(手工解决方案也应具有此性能)进行仔细实施来避免这种情况。遗漏的异常也可能是先入为主或懒惰,因为它需要努力定义和实现异常ABI。
Jan Hudec 2012年

4

我不了解复杂性(实现的效率),但是我广泛使用Qt容器和字符串而不是标准容器和字符串,它们可以正常工作。我还发现集和列表的Qt实现更易于使用。

因此,如果可以使用其他满足您需要的库,则放弃STL是很实际的。


2
当没有a)可用或b)任何良好的STL实现时,就可以创建Qt等效项。这是它们仍然被使用的唯一原因,没有违反当今的STL。
gbjbaanb

1
@ Giorgio:问题出在复杂的应用程序中,您在其中组合了多个库。作为标准的STL容器形成一种通用语言。更确切地说,这是他们的惯例。最著名的例子是Boost。它可以在STL容器上工作。它也可以在Qt容器上工作,但这仅是因为Qt遵循STL约定-例如QList<T>::iterator
MSalters 2012年

3
我没有对此投票,但我看到一个原因:它不能回答问题。您说可以代替STL使用某些东西,这很好,但这不是避免STL的原因。除了避免STL的任何原因外,Qt,MFC和其他此类库也可能甚至更多。
Jan Hudec

3
@NoOne:我们知道您习惯于驼峰旅行箱,而不是蛇形旅行箱,但这不会使后者变得更糟。在您批评的三个函数名中,第一个是对与c字符串有任何关系的人的完美描述,另外两个是从C继承的,因此不再讨论。
Deduplicator 2015年

1
@NoOne:正如我所说,我完全知道您对CamelCase感到更舒服。
Deduplicator 2015年

3

Patrick提到了不使用整个STL的原因,即您的平台没有一个。

总而言之,我认为这个问题没有抓住重点。这基本上不是一个全有或全无的决定,而是一个选择的选择。您可能会决定使用容器和算法,但决定将Std Lib之外的内容用于字符串和I / O。


3

除非有充分的理由,否则这是不实际的。我可以想到的一些这样的原因包括您仅需解决的STL(或标准库的任何其他部分)的部分实现或缺乏实现或资源限制(内存,CPU速度,存储等)。滚动您自己的工具,使其符合您需要完成的工作。

在游戏行业中,大多数(甚至在某种程度上甚至更小)工作室都具有内部库和许多标准库部件的实现,这些库部件高度适合目标平台,在某些情况下还针对英语甚至游戏本身。简而言之,在开发游戏机游戏时,硬件受当今标准的限制。出于某种原因,有成千上万的手工装配线。最大限度地减少代码中的各种资源占用非常重要,这样游戏才能更快地运行,从而可以在游戏世界(例如更大的世界)中提供更多内容,从而有望带来更好的产品。

“每个成功的游戏都始于推出自己的链表实现。”


1
我可以想象每一个成功的游戏都是从使用标准库编写代码开始,然后在对游戏进行了广泛介绍之后才对代码进行优化。在对数据进行概要分析以表明需要优化的内容之前进行优化是没有意义的。
Cromulent

真正。最后一句话只是90年代初左右“古老”的编写游戏方式的一种玩法,当时C ++并未得到广泛部署,而汇编+ C是必经之路。也许我应该更清楚一点。尽管它在控制台中很好地适用于游戏行业,但是大多数算法和数据结构默认情况下都是手写的,因为每个字节和周期都很重要(是的,即使是以可维护性/可移植性/其他为代价)。
zxcdw 2012年

2
应该说,这更多的是一种古老的经验。与通过程序员手工编写相比,现代优化程序通常可以通过简单的可维护代码生成更好的汇编,并且像STL或Boost中那样的通用模板通常会内联成高效的代码,就像手工编写所有内容一样。但是有很多代码是在不是这种情况的时候开始的,并且很多人在那段时间学习了交易并且以这种方式继续工作,即使这不再有意义了。
Jan Hudec 2012年

2
@JanHudec问题是实现(实际上也包括行为)需要非常适合该任务。您只是不能在这里和那里保留几十个字节(破坏引用的局部性),放下几个分支来验证输入(分支错误预测和指令高速缓存未命中),并假设编译器知道如何向量化您的数据结构最佳地利用SIMD(它不会,或者至少您必须验证它的尝试是正确的)。当然,在PC上编写实时软件并不那么严格,您总是可以使用更快的CPU。不在控制台中。
zxcdw 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.