C++ STL替代方案

C++ STL替代方案,c++,performance,stl,debug-build,C++,Performance,Stl,Debug Build,我真的很讨厌使用STL容器,因为它们使我的代码的调试版本运行得非常慢。其他人使用什么来代替STL,它对调试构建具有合理的性能 我是一名游戏程序员,这在我从事的许多项目中都是一个问题。当您使用STL容器处理所有内容时,很难获得60 fps 我的大部分工作都使用MSVC。我敢打赌,您的STL使用检查过的实现进行调试。这可能是一件好事,因为它将捕获迭代器溢出等。如果这对您来说是一个很大的问题,那么可能会有一个编译器开关将其关闭。检查您的文档。STL容器不应在调试或其他任何地方“非常缓慢”地运行。也许你

我真的很讨厌使用STL容器,因为它们使我的代码的调试版本运行得非常慢。其他人使用什么来代替STL,它对调试构建具有合理的性能

我是一名游戏程序员,这在我从事的许多项目中都是一个问题。当您使用STL容器处理所有内容时,很难获得60 fps


我的大部分工作都使用MSVC。

我敢打赌,您的STL使用检查过的实现进行调试。这可能是一件好事,因为它将捕获迭代器溢出等。如果这对您来说是一个很大的问题,那么可能会有一个编译器开关将其关闭。检查您的文档。

STL容器不应在调试或其他任何地方“非常缓慢”地运行。也许你误用了它们。在调试中,您不会遇到类似ElectricFence或Valgrind的东西,是吗?它们会减慢任何需要大量分配的事情


所有的容器都可以使用自定义分配器,有些人使用它来提高性能,但我从来没有需要使用它们。

< P>如果你使用VisualC++,那么你应该看看这个:

以及该页面的链接,其中包含MS/Dinkware STL所做的所有调试模式检查的各种成本和选项


如果你要问这样一个与平台有关的问题,最好提一下你的平台……

签出。

Test+++有自己的一套容器-不确定你是否可以从其他库中使用它们:

如果你运行的Visual Studio你可能想考虑以下内容:

#define _SECURE_SCL 0
#define _HAS_ITERATOR_DEBUGGING 0

这只是针对迭代器,您正在执行什么类型的STL操作?你可能想看看优化你的内存操作;例如,使用resize()一次插入多个元素,而不是使用pop/push一次插入一个元素。

?它是一个面向对象的开源并发通信软件框架,但也有一些容器类。

我的经验是,设计良好的STL代码在调试版本中运行缓慢,因为优化器关闭了。STL容器向构造函数和operator=发出大量调用,这些调用(如果它们很轻的话)在发布版本中内联/删除

此外,Visual C++ 2005和UP在发布和调试版本中都为STL启用了检查。这对于STL重型软件来说是一个巨大的性能瓶颈。可以通过为所有编译单元定义_SECURE_SCL=0来禁用它。请注意,在不同的编译单元中具有不同的SCL状态几乎肯定会导致灾难


您可以在禁用检查的情况下创建第三个构建配置,并使用该配置进行性能调试。不过,我建议您保留一个带有检查功能的调试配置,因为捕获错误的数组索引和类似的东西非常有帮助。

EASTL是一种可能性,但仍然不是完美的。Electronic Arts的Paul Pedriana对各种STL实现在游戏应用程序中的性能进行了调查,总结如下:

<> P>这些调整中的一些被审查以包含在C++标准中。

注意,即使是EASTL也没有针对非优化情况进行优化。前一段时间我有一个excel文件,但我想我已经丢失了,但对于access来说,它是这样的:

       debug   release
STL      100        10
EASTL     10         3
array[i]   3         1

我所取得的最大成功就是滚动我自己的容器。您可以将其归结为近阵列[x]性能。

对于性能关键的大型应用程序,构建专门针对您需要的容器可能是值得投资的时间


我在这里讨论的是真正的游戏开发。

< P>用面向对象的设计模式在C++中检查数据结构和算法 布鲁诺·普里斯
MSVC在调试版本中使用了一个非常重的检查迭代器实现,其他人已经讨论过了,所以我不再重复(但从这里开始)

您可能感兴趣的另一件事是,“调试构建”和“发布构建”可能涉及更改(至少)4个仅松散相关的设置

  • 生成一个.pdb文件(cl/Zi和link/DEBUG),它允许符号调试。您可能需要向链接器选项添加/OPT:ref;当不生成.pdb文件时,链接器会删除未引用的函数,但在/DEBUG模式下,链接器会保留所有未引用的函数(因为调试符号引用了这些函数),除非您明确地添加这些函数
  • 使用调试版本的C运行时库(可能是MSVCR*D.dll,但这取决于您使用的运行时)。这可以归结为/MT或/MTd(如果不使用dll运行时,也可以是其他内容)
  • 关闭编译器优化(/Od)
  • 设置预处理器#定义调试或NDEBUG
  • 这些可以独立切换。第一种方法在运行时性能方面没有任何成本,但它增加了大小。第二种方法使许多函数更昂贵,但对malloc和free有巨大的影响;调试运行时版本小心地用值“毒害”内存,以清除未初始化的数据错误。我相信在MSVCP*STL实现中,它还消除了通常所做的所有分配池,因此泄漏会准确地显示您所想的块,而不是它所分配的更大的内存块;这意味着它会向malloc打更多的电话,而且速度要慢得多。第三,;嗯,那个人做了很多事情(对这个问题有很好的讨论)。不幸的是,如果您希望单步顺利地工作,就需要它。第四种方法以各种方式影响许多库,但最值得注意的是,它在assert()和friends中编译或消除了assert()

    <>所以你可以考虑用这些选择的一些较小的组合来构建。我经常使用具有符号(/Zi和link/DEBUG)和断言(/DDEBUG)但仍然优化(/O1或/O2或您使用的任何标志)但