【问题标题】:STL container for a list with random access?用于随机访问列表的 STL 容器?
【发布时间】:2012-09-16 03:16:35
【问题描述】:

是否存在类似于列表的 STL 容器,其中列表的元素不是连续存储的?这个容器的大小最多可以是 1000x1000 个元素,每个元素都是一个包含 36 个双精度数的向量。这将是一个大块存储在一起(如约 200 兆字节)。是否有一种变体将指向其内容的指针存储为单独的向量,以便允许随机访问。是否有一个已经存在的 STL 容器类,或者我应该手动存储指针?

我需要的容器实际上是一个恒定大小,所以我认为自己实现它不会太困难,但我想知道是否已经存在一个 STL 容器。我想避免使用向量,因为列表很大并且内容将是中等大小。如果容器中的向量不需要彼此相邻,那么将它们分隔在一个列表中以防止内存不足会更好吗?

【问题讨论】:

  • 所以...你想要的是std::array<std::unique_ptr<T>, length>?
  • 您关注std::vector<T>std::array<T, n>的哪方面的表现?
  • 好的,你不需要容器是连续的。这不是避免 vectorarray 的理由!
  • 在哪些方面类似于list?在迭代器中快速插入/删除?元素永远不会重新定位?如果您只需要一个序列,那么标准序列(除了array)是vectordequelist。就连续性而言,vector 是连续的,deque 不必是连续的,但它具有随机访问权限,对于中间插入/删除之类的操作,它不需要比原来更快,list 是非连续性并保证非连续性的好处(和缺点)。
  • @MooingDuck:我不清楚外部容器必须持有一个向量:尽管提问者说它会,但人们勇敢地支持@987654334 @ 用于固定大小的行,所以我想介绍这种情况。但如果它确实持有vector,则同意。在你开始用完总内存之前它不会变得非常大,所以它不会在最大尺寸上产生超过(比如说)2倍的差异。

标签: c++ stl


【解决方案1】:

deque<array<double, 36>>vector<vector<double>> 都将避免需要任何非常大的连续分配。

vector<vector<double>> 在这些方面更糟。对于您指定的数字,它需要1000*1000*sizeof(vector<double>) 的连续分配,这是低 10 秒的 MB(很可能vector 是 3 个指针的大小)。这在“适当的计算机”(台式机或服务器)上很少出现问题。由于碎片原因(小虚拟地址空间或根本没有虚拟地址),您可能还会遇到更根本的问题,即您没有 300MB 左右的 RAM。但是您可以通过避免它来保证安全,因为显然存在可以分配总共 300MB 但不能连续分配 12MB 的环境。

C++03 中没有 std::array,但有 boost::array,或者您可以轻松编写一个类来表示 36 个双精度数。

vector<array<double, 36>> 受碎片影响最严重,它需要连续分配 250 MB。就个人而言,我发现在测试“我们将面临的最糟糕的内存碎片”时模拟并不容易,但我不是最好的测试人员。这个块的大小大约是我在 32 位进程中开始感到有点不安的地方,但在良好的条件下它会正常工作。

【讨论】:

    【解决方案2】:

    目前尚不清楚您究竟追求std::list<T> 的什么特征。如果您想要一个在添加或删除元素时元素保持原样的容器,您可能需要查看std::deque<T>:在前面或后面添加/删除元素时,所有其他元素都保持在同一位置。也就是说,指向元素的指针和引用保持有效,除非在中间添加或删除元素。迭代器在任何插入或删除时都无效。 std::deque<T> 提供随机访问。

    没有容器直接给予随机访问并支持在任何位置添加/删除元素保持原样。但是,正如其他人指出的那样,使用指针容器提供了这样的接口。可能需要包装它以隐藏指针的使用。

    【讨论】:

      【解决方案3】:

      我强烈建议您使用std::array 类。它是固定大小的,它支持对所有元素的随机访问,并具有iterator, const_iterator, reverse_iterator, const_reverse_iterator 的实现。更多信息:http://www.cplusplus.com/reference/stl/array/

      【讨论】:

      • 根据我的阅读,整个数组是连续的。对于我的应用程序,我只希望行(或列)是连续的。
      • @user1346994:仅仅因为它不需要需要是连续的,并不意味着它不能是连续的。连续是非常快。我们推荐它是有原因的。
      猜你喜欢
      • 2012-06-03
      • 1970-01-01
      • 1970-01-01
      • 2010-12-15
      • 1970-01-01
      • 2015-01-05
      • 1970-01-01
      • 1970-01-01
      • 2020-07-01
      相关资源
      最近更新 更多