STL/标准C++容器的最佳效率如何



我在SO:上读到这篇文章

https://stackoverflow.com/a/3183607/997112

这是对C++和C#之间的性能问题的回答。海报来自高频交易背景,并表示由于寻求纳秒级的节约,他为高频工作编写了自己的课程库。在他的帖子中,他提到他很少使用C++STL,这让我很惊讶

我的问题是,C++STL在性能方面是完全优化的,还是只针对普通用户进行了优化?用C语言在一个原生数组周围封装几个函数会比Vector或List更快吗?boost中是否有性能更好的容器?

我很感激这些类对99%的用户来说足够快,但我的问题是针对其他1%的用户。

这个问题不会得到任何答案,说明"STL是最优的"有很多原因:

  1. STL的实现至少有六种,当然有些没有优化,而另一些已经优化(但请参阅下一项)
  2. 您所做的大多数优化都是对使用模式进行假设的,对于某些使用模式来说,这将是令人讨厌的。要真正针对特定用例进行优化,需要了解如何使用某些东西
  3. 大多数STL用户以这样或那样的形式滥用组件,只有C++2011才真正支持某些正确的使用(例如,使用本地自定义分配器)
  4. 当人们谈论STL时,他们通常指的是带有算法的集装箱运输示例。尽管STL很有用,但它的重点是算法,这些算法有更好的优化机会。毕竟,STL的全部意义在于,您可以很容易地将算法用于自定义创建的容器!为什么要麻烦优化容器?然而,请注意,第1项至第3项也适用于算法
  5. STL有一个很好的抽象,但并不完全"存在"。特别是,当组合多个算法时,存在比单独应用算法更好的方法,但STL接口并不真正支持这一点

也就是说,要想找到比典型的优化STL实现更好的东西,需要付出相当多的努力。我会质疑任何人的断言,比如说,他们在一天内为std::vector<T, A>编写了一个替换,并声称在std::vector<T, A>的典型用例中速度更快(指的是C++2011版本,在该版本中可以合理地使用分配器)。

C++03在复制方面有一个非常明显的性能问题,但在C++11中通过移动语义和完美的转发解决了这个问题。

规范定义了所有标准算法的复杂性,因此您可以预期所有实现的特定性能行为。

通常,当人们抱怨stdlib的性能时,他们使用了错误的工具,只需要改进他们的算法。C++提供了很多东西,但它从不假装一件事适用于所有事情。

我发现stdlib集合缺少两件事:

当您想从游泳池或竞技场分配藏品时。分配器(甚至是有状态的)不够灵活,无法在所有情况下都实现零开销。

此外,有时实现某些东西最有效的方法是合并两个集合。例如,对于缓存,您可能希望合并unordered_maplist,分别用于查找和LRU。标准集合并不能使其非常高效。

在这两种情况下,Boost Intrusive都提供了所需的功能。

从实际阅读帖子来看,这一点很突出:

">所有自定义同步类都只在空时同步,自定义分配器,自定义免锁队列和列表,偶尔的STL(带有自定义分配器),但更多时候是自定义侵入式集合(我有一个重要的库)。">

STL是为处理多个读取线程而设置的,但当然需要锁和其他同步原语来处理多个写入程序。如果作者真的编写了自定义的无锁队列和列表,那么与带锁的纯STL相比,它可能会大大提高性能。自定义分配器几乎是意料之中的事,默认的std::allocator<T>是一个"中间路线"类型的解决方案。根据分配模式,使用带有内存池的分配器可以提供显著的加速。

最新更新