You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何自行实现的简易Vector的push_back性能优于STL版本?

为什么自定义Vector的push_back比std::vector快8倍?

我基于Weiss的C++数据结构教材实现了一个简易Vector类,在执行100000次push_back操作时耗时0.001秒;而使用std::vector执行完全相同的测试时,耗时0.008秒,速度约慢8倍。请问造成这种差异的原因是什么?

#include <iostream>
#include <algorithm>
#include <ctime>
#include <vector>

template<typename Object>
class Vector {

public:

    // normal constructor
    explicit Vector(int initialSize = 0) :
        theSize{ initialSize }, theCapacity{ initialSize + SPARE_CAPACITY },
        objects{ new Object[theCapacity] }
    {}

    // copy constructor
    Vector(const Vector& rhs) :
        theSize{ rhs.theSize }, theCapacity{ rhs.theCapacity }, objects{ nullptr }
    {
        objects = new Object[theCapacity];
        for (int k = 0; k < theSize; ++k)
            objects[k] = rhs.objects[k];
    }

    // copy assignment operator
    Vector& operator=(const Vector& rhs)
    {
        Vector copy = rhs;
        std::swap(*this, copy);
        return *this;
    }

    // destructor
    ~Vector()
    {
        delete[] objects;
    }

    // move constructor
    Vector(Vector&& rhs) :
        theSize{ rhs.theSize }, theCapacity{ rhs.theCapacity }, objects{ rhs.objects }
    {
        rhs.objects = nullptr;
        rhs.theSize = 0;
        rhs.theCapacity = 0;
    }

    // move assignment operator
    Vector& operator=(Vector&& rhs)
    {
        std::swap(theSize, rhs.theSize);
        std::swap(theCapacity, rhs.theCapacity);
        std::swap(objects, rhs.objects);

        return *this;
    }

    void resize(int newSize)
    {
        if (newSize > theCapacity)
            reserve(newSize * 2); // talk about amortized time (python book)
        theSize = newSize;
    }

    void reserve(int newCapacity)
    {
        if (newCapacity < theSize)
            return;

        Object* newArray = new Object[newCapacity];
        for (int k = 0; k < theSize; ++k)
            newArray[k] = std::move(objects[k]);

        theCapacity = newCapacity;
        std::swap(objects, newArray);
        delete[] newArray;
    }

    Object& operator[](int index)
    {
        return objects[index];
    }

    const Object& operator[](int index)const
    {
        return objects[index];
    }

    bool empty() const
    {
        return size() == 0;
    }

    int size() const
    {
        return theSize;
    }

    int capacity() const
    {
        return theCapacity; 
    }

    void push_back(const Object& x)
    {
        if (theSize == theCapacity)
            reserve(2 * theCapacity + 1);

        objects[theSize++] = x; 
    }

    void push_back(Object&& x)
    {
        if (theSize == theCapacity)
            reserve(2 * theCapacity + 1);

        objects[theSize++] = std::move(x); 
    }

    void pop_back()
    {
        --theSize;
    }

    const Object& back() const
    {
        return objects[theSize - 1];
    }

    // iterator
    typedef Object* iterator;
    typedef const Object* const_iterator;

    iterator begin()
    {
        return &objects[0];
    }
    const_iterator begin() const
    {
        return &objects[0];
    }
    iterator end()
    {
        return &objects[size()];
    }
    const_iterator end() const
    {
        return &objects[size()];
    }

    static const int SPARE_CAPACITY = 16; 

private:
    int theSize;
    int theCapacity;
    Object* objects; 
};


int main()
{
    std::clock_t start;
    start = std::clock(); 
    std::vector<int> vec2{ 0 };
    for (int i = 0; i < 100000; i++)
        vec2.push_back(i);
    double duration = (std::clock() - start) / (double)CLOCKS_PER_SEC;

    std::cout << "printf: " << duration << '\n';


    start = std::clock();       
    Vector<int> vec{ 0 };
    for (int i = 0; i < 100000; i++)
        vec.push_back(i);

    duration = (std::clock() - start) / (double)CLOCKS_PER_SEC;

    std::cout << "printf: " << duration << '\n';
}

核心原因分析

1. 测试流程的系统性偏差

  • 缓存预热效应:你先测试std::vector再测试自定义Vector,第一次测试会触发内存页分配、CPU缓存加载等系统级开销,第二次测试时这些资源已经就绪,自然速度更快。交换两次测试顺序,结果很可能反转。
  • 时钟精度限制:std::clock()的精度有限,对于仅耗时几毫秒的操作,测量结果容易出现较大误差,单次测试的参考价值很低。

2. 实现细节的差异

  • 调试模式额外开销:如果测试是在Debug编译模式下进行,std::vector会包含大量调试检查(比如边界越界检测、迭代器有效性验证、内存填充哨兵值等),这些都是自定义Vector没有的额外开销,会显著拖慢速度。Release模式下这些检查会被移除。
  • 扩容策略与次数:自定义Vector初始容量为16(SPARE_CAPACITY=16),扩容公式是2*capacity+1;而std::vector的初始容量和扩容策略依赖具体实现,比如很多实现初始容量从1开始,每次扩容翻倍。对于100000次push_back,std::vector的扩容次数会比自定义Vector多,每次扩容的内存拷贝开销累积起来会形成差距。
  • 内存分配器的复杂度:std::vector使用标准分配器std::allocator,其实现会考虑内存对齐、线程安全、内存池兼容等通用场景,相比自定义Vector直接用new[]的简单分配,会有额外的逻辑开销。
  • 编译器优化空间:自定义Vector的代码逻辑更简洁直白,编译器更容易进行深度优化;而std::vector作为标准库组件,代码包含更多通用兼容逻辑,编译器优化的难度更高,尤其是在未开启最高优化等级时。

3. 测试严谨性不足

单次测试的结果受环境影响极大,正确的测试方式应该:

  • 开启最高等级优化(如-O3)
  • 交换测试顺序,多次测试取平均值
  • 控制变量,确保两个容器的初始状态完全一致(比如都从空容器开始测试,而非初始包含一个元素)

内容的提问来源于stack exchange,提问作者Russell Butler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 09:46:06