揭秘C++ vector的魔法:resize() vs reserve(),性能优化的关键

在C++中,std::vector是最常用的容器之一,它提供了动态数组的功能。vector类有两个常用但经常被误解的成员函数:resize()和reserve()。理解这两个函数的区别和正确使用方法,可以显著提升你的程序性能。让我们深入探讨这两个函数的特性和用法。

  1. resize() 函数

作用:

  • 改变vector中元素的数量
  • 如果新尺寸大于当前尺寸,会在末尾添加新元素
  • 如果新尺寸小于当前尺寸,会删除末尾的元素

语法:

void resize(size_type new_size);
void resize(size_type new_size, const value_type& value);

特点:

  • 会改变vector的size()
  • 可能会改变vector的capacity()
  • 如果指定了value参数,新添加的元素会被初始化为这个值

示例:

std::vector<int> v = {1, 2, 3};
v.resize(5);  // v becomes {1, 2, 3, 0, 0}
v.resize(2);  // v becomes {1, 2}
v.resize(4, 10);  // v becomes {1, 2, 10, 10}

  1. reserve() 函数

作用:

  • 预分配内存空间,但不创建任何元素
  • 增加vector的capacity,但不改变它的size

语法:

void reserve(size_type new_cap);

特点:

  • 只改变vector的capacity(),不改变size()
  • 如果new_cap大于当前capacity,会重新分配内存
  • 如果new_cap小于或等于当前capacity,函数不做任何事

示例:

std::vector<int> v;
v.reserve(10);  // capacity becomes 10, size is still 0
v.push_back(1);  // size becomes 1, capacity is still 10

关键区别:

  1. 对元素的影响

    • resize()会实际创建或销毁元素
    • reserve()不创建任何元素,只预分配内存
  2. 对size()的影响

    • resize()改变size()
    • reserve()不改变size()
  3. 对capacity()的影响

    • resize()可能改变capacity()
    • reserve()只增加capacity(),不减少
  4. 性能影响

    • resize()可能涉及元素的构造或析构,可能较慢
    • reserve()只涉及内存分配,通常较快
  5. 使用场景

    • resize()用于实际需要特定数量元素时
    • reserve()用于提前知道大概需要多少元素,想要避免多次重新分配内存时

性能优化示例:

不使用reserve():

std::vector<int> v;
for (int i = 0; i < 10000; ++i) {
    v.push_back(i);  // 可能导致多次内存重新分配
}

使用reserve():

std::vector<int> v;
v.reserve(10000);  // 一次性分配足够的内存
for (int i = 0; i < 10000; ++i) {
    v.push_back(i);  // 不会导致内存重新分配
}

在这个例子中,使用reserve()可以显著提高性能,因为它避免了多次内存重新分配。

深入理解:

  1. 内存重分配
    当vector的size超过其capacity时,会发生内存重分配。这个过程涉及:

    • 分配新的更大的内存块
    • 将所有元素复制或移动到新内存
    • 释放旧内存
      这是一个耗时的操作,特别是对于大型vector。
  2. 增长策略
    不同的C++标准库实现可能有不同的vector增长策略。常见的策略是每次增长将capacity翻倍,这样可以平摊重分配的成本。

  3. 内存使用
    reserve()可以帮助减少内存碎片,因为它允许一次性分配大块内存,而不是多次小额分配。

  4. 异常安全
    resize()可能会抛出异常(如果元素的构造函数抛出异常),而reserve()通常不会(除非内存分配失败)。

实际应用示例:

  1. 高效地构建大型vector:
std::vector<MyClass> objects;
objects.reserve(1000000);  // 预分配内存,避免频繁重分配
for (int i = 0; i < 1000000; ++i) {
    objects.emplace_back(/* 构造参数 */);  // 使用emplace_back直接在vector中构造对象
}

  1. 使用resize()初始化vector:
std::vector<int> data;
data.resize(100, 42);  // 创建100个元素,所有元素值为42

结论:
正确理解和使用resize()和reserve()可以显著提高你的程序性能。resize()用于改变vector中实际元素的数量,而reserve()用于优化内存分配。在你知道vector大概需要多少元素时,使用reserve()可以避免不必要的内存重分配,从而提高性能。

记住,优化是一门平衡的艺术。过度使用reserve()可能会导致内存浪费,而不使用它则可能导致性能下降。理解你的数据结构和算法需求,根据实际情况做出明智的选择。

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值