[c++] std中vector和list 效率探究

本文分析了C++STL中的std::vector和std::list在随机访问、插入和删除操作中的性能差异。std::vector适合随机访问和尾部插入,但中间操作效率低;std::list适合频繁插入/删除,但不支持随机访问。
摘要由CSDN通过智能技术生成

提示:-


前言

在C++ STL中,std::vector和std::list是两种常用的容器,它们在内部实现和性能特点上有所不同。

  • std::vector适合需要随机访问和尾部插入的场景
  • std::list适合频繁的插入和删除操作

∴选择合适的容器取决于具体的需求和操作频率。


提示:以下是本篇文章正文内容,下面案例可供参考

一.std::vector 特点

1.底层基于动态数组实现,支持随机访问。
2.内存连续存储,可以高效地访问元素,适合大量元素的访问和尾部插入。
3.在尾部插入和访问元素时性能较好,但在中间插入或删除元素时可能需要移动大量元素,效率较低。
4.支持动态扩容,当元素数量超过容量时会重新分配内存,可能导致迭代器失效。

二、std::list 特点

1.底层基于双向链表实现,不支持随机访问,只能通过迭代器进行顺序访问。
2.插入和删除元素时效率高,不需要移动其他元素,适合频繁的插入和删除操作。
3.内存非连续存储,每个元素都包含指向前后元素的指针,占用额外的空间
4.不支持随机访问,访问元素时需要遍历链表,性能较差。


三、代码示例

#include <iostream>
#include <vector>
#include <list>
#include <chrono>
#include <algorithm>
int main() 
{
    const int dataSize = 10000;
    std::vector<int> vec;
    std::list<int> lst;

    // 向vector和list中插入1000个数据
    auto start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < dataSize; i++) {
        vec.push_back(i);
    }
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> insertVecTime = end - start;

    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < dataSize; i++) {
        lst.push_back(i);
    }
    end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> insertListTime = end - start;

    // 在vector和list中查找数据
    start = std::chrono::high_resolution_clock::now();
    auto itVec = std::find(vec.begin(), vec.end(), 500);
    end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> findVecTime = end - start;

    start = std::chrono::high_resolution_clock::now();
    auto itList = std::find(lst.begin(), lst.end(), 500);
    end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> findListTime = end - start;

    // 从vector和list中删除数据
    start = std::chrono::high_resolution_clock::now();
    vec.erase(vec.begin() + 500);
    end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> eraseVecTime = end - start;

    start = std::chrono::high_resolution_clock::now();
    lst.remove(500);
    end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> eraseListTime = end - start;

    // 输出耗时结果
    std::cout << "Vector Insert Time: " << insertVecTime.count() << " seconds\n";
    std::cout << "List Insert Time: " << insertListTime.count() << " seconds\n";
    std::cout << "Vector Find Time: " << findVecTime.count() << " seconds\n";
    std::cout << "List Find Time: " << findListTime.count() << " seconds\n";
    std::cout << "Vector Erase Time: " << eraseVecTime.count() << " seconds\n";
    std::cout << "List Erase Time: " << eraseListTime.count() << " seconds\n";

    return 0;
}

/* Result: 
    Vector Insert Time: 0.00017399 seconds
    List Insert Time: 0.000754313 seconds
    Vector Find Time: 3.142e-06 seconds
    List Find Time: 7.706e-06 seconds
    Vector Erase Time: 1.652e-06 seconds
    List Erase Time: 0.000110425 seconds
*/

总结

向std::vector中插入数据的耗时(0.00017399秒)要比向std::list中插入数据的耗时(0.000754313秒)短。
在std::vector中查找数据的耗时(3.142e-06秒)要比在std::list中查找数据的耗时(7.706e-06秒)短。
从std::vector中删除数据的耗时(1.652e-06秒)要比从std::list中删除数据的耗时(0.000110425秒)短。
根据这些数据,可以得出以下结论:

对于尾部插入操作,std::vector的性能优于std::list。
对于查找操作,std::vector的性能优于std::list。
对于删除操作,std::vector的性能优于std::list。

这与之前提到的std::vector适合随机访问和尾部插入的特点相符合,因为在这些操作中std::vector的连续内存存储和随机访问特性能够提供更好的性能。而std::list由于是双向链表实现,对于插入和删除操作的性能更优。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值