C++ STL中的list和vector如何选择?C++容器性能对比分析

来源:站长联盟作者:台湾程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《C++ STL中的list和vector如何选择?C++容器性能对比分析》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++ STL中的list和vector如何选择?C++容器性能对比分析》有用,将其分享出去将是对创作者最好的鼓励。

在C++标准模板库STL中,list和vector都是常用的序列式容器,两者的底层实现逻辑完全不同,因此性能表现和适用场景也存在显著差异,开发者需要根据实际需求合理选择。

C++ STL中的list和vector如何选择?C++容器性能对比分析

底层数据结构差异

vector的底层是连续的内存空间,本质是一个动态数组,元素在内存中依次排列,支持随机访问。list的底层是双向链表,每个节点包含数据域、前驱指针和后继指针,节点在内存中离散分布,不支持随机访问。

常用操作性能对比

我们可以从增删改查几个核心操作维度,对比两者的性能表现:

操作类型vectorlist
随机访问时间复杂度O(1),通过下标直接定位元素时间复杂度O(n),需要遍历链表查找
尾部插入/删除平均O(1),空间不足时扩容需要O(n)复制元素时间复杂度O(1),只需要修改指针指向
中间插入/删除时间复杂度O(n),需要移动后续所有元素时间复杂度O(1),只需要修改相邻节点的指针
内存占用额外开销小,只存储元素本身,可能有预留空间浪费每个节点额外存储两个指针,内存开销更大

代码示例验证

下面通过一段测试代码,直观展示两者在随机访问和中间插入操作上的性能差异:

#include <iostream>
#include <vector>
#include <list>
#include <chrono>

int main() {
    const int TEST_SIZE = 100000;
    std::vector<int> test_vec;
    std::list<int> test_list;

    // 先填充100000个元素
    for (int i = 0; i < TEST_SIZE; ++i) {
        test_vec.push_back(i);
        test_list.push_back(i);
    }

    // 测试随机访问性能
    auto start = std::chrono::high_resolution_clock::now();
    int sum = 0;
    for (int i = 0; i < TEST_SIZE; ++i) {
        sum += test_vec[i]; // vector随机访问
    }
    auto end = std::chrono::high_resolution_clock::now();
    auto vec_access_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    std::cout << "vector随机访问耗时: " << vec_access_time.count() << "微秒" << std::endl;

    start = std::chrono::high_resolution_clock::now();
    sum = 0;
    auto it = test_list.begin();
    for (int i = 0; i < TEST_SIZE; ++i) {
        sum += *it; // list需要遍历访问
        ++it;
    }
    end = std::chrono::high_resolution_clock::now();
    auto list_access_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    std::cout << "list随机访问耗时: " << list_access_time.count() << "微秒" << std::endl;

    // 测试中间插入性能
    start = std::chrono::high_resolution_clock::now();
    test_vec.insert(test_vec.begin() + TEST_SIZE/2, 999); // vector中间插入
    end = std::chrono::high_resolution_clock::now();
    auto vec_insert_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    std::cout << "vector中间插入耗时: " << vec_insert_time.count() << "微秒" << std::endl;

    start = std::chrono::high_resolution_clock::now();
    auto list_it = test_list.begin();
    for (int i = 0; i < TEST_SIZE/2; ++i) ++list_it;
    test_list.insert(list_it, 999); // list中间插入
    end = std::chrono::high_resolution_clock::now();
    auto list_insert_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    std::cout << "list中间插入耗时: " << list_insert_time.count() << "微秒" << std::endl;

    return 0;
}

运行上述代码可以看到,vector的随机访问耗时远低于list,而list的中间插入耗时远低于vector,和理论分析的结论一致。

选型建议

结合两者的特性,我们可以按照以下场景选择容器:

  • 如果需要频繁随机访问元素,或者主要在尾部进行增删操作,优先选择vector,比如存储数组数据、实现栈结构等场景。
  • 如果需要频繁在中间位置插入或删除元素,且不需要随机访问,优先选择list,比如实现链表结构、频繁调整元素顺序的场景。
  • 如果元素数量较少,且操作频率不高,两者的性能差异可以忽略,选择vector即可,因为vector的内存局部性更好,缓存命中率更高。
注意:vector扩容时会重新分配内存并复制所有元素,如果提前知道元素大致数量,可以通过reserve方法预留空间,减少扩容带来的性能损耗。

listvectorC++_STL容器性能对比修改时间:2026-07-01 13:57:28

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。