小编典典

std::vector 比普通数组慢很多吗?

all

我一直认为这std::vector是“作为数组实现”的普遍智慧,等等等等。今天下楼测试了一下,好像不是这样:

以下是一些测试结果:

UseArray completed in 2.619 seconds
UseVector completed in 9.284 seconds
UseVectorPushBack completed in 14.669 seconds
The whole thing completed in 26.591 seconds

这大约慢了 3 - 4 倍!并不能真正证明“vector可能会慢几纳秒”的评论。

我使用的代码:

#include <cstdlib>
#include <vector>

#include <iostream>
#include <string>

#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/microsec_time_clock.hpp>

class TestTimer
{
    public:
        TestTimer(const std::string & name) : name(name),
            start(boost::date_time::microsec_clock<boost::posix_time::ptime>::local_time())
        {
        }

        ~TestTimer()
        {
            using namespace std;
            using namespace boost;

            posix_time::ptime now(date_time::microsec_clock<posix_time::ptime>::local_time());
            posix_time::time_duration d = now - start;

            cout << name << " completed in " << d.total_milliseconds() / 1000.0 <<
                " seconds" << endl;
        }

    private:
        std::string name;
        boost::posix_time::ptime start;
};

struct Pixel
{
    Pixel()
    {
    }

    Pixel(unsigned char r, unsigned char g, unsigned char b) : r(r), g(g), b(b)
    {
    }

    unsigned char r, g, b;
};

void UseVector()
{
    TestTimer t("UseVector");

    for(int i = 0; i < 1000; ++i)
    {
        int dimension = 999;

        std::vector<Pixel> pixels;
        pixels.resize(dimension * dimension);

        for(int i = 0; i < dimension * dimension; ++i)
        {
            pixels[i].r = 255;
            pixels[i].g = 0;
            pixels[i].b = 0;
        }
    }
}

void UseVectorPushBack()
{
    TestTimer t("UseVectorPushBack");

    for(int i = 0; i < 1000; ++i)
    {
        int dimension = 999;

        std::vector<Pixel> pixels;
            pixels.reserve(dimension * dimension);

        for(int i = 0; i < dimension * dimension; ++i)
            pixels.push_back(Pixel(255, 0, 0));
    }
}

void UseArray()
{
    TestTimer t("UseArray");

    for(int i = 0; i < 1000; ++i)
    {
        int dimension = 999;

        Pixel * pixels = (Pixel *)malloc(sizeof(Pixel) * dimension * dimension);

        for(int i = 0 ; i < dimension * dimension; ++i)
        {
            pixels[i].r = 255;
            pixels[i].g = 0;
            pixels[i].b = 0;
        }

        free(pixels);
    }
}

int main()
{
    TestTimer t1("The whole thing");

    UseArray();
    UseVector();
    UseVectorPushBack();

    return 0;
}

我做错了什么吗?还是我刚刚打破了这个性能神话?

我在Visual Studio
2005
中使用发布模式。


Visual
C++
中,#define _SECURE_SCL 0减少UseVector一半(减少到 4 秒)。这真的很大,IMO。


阅读 74

收藏
2022-06-02

共1个答案

小编典典

使用以下内容:

g++ -O3 Time.cpp -I
./a.out
UseArray
在 2.196 秒内完成 UseVector 在 4.412 秒内
完成 UseVectorPushBack在 8.017 秒内完成
整个事情在 14.626 秒内完成

所以数组的速度是向量的两倍。

但是
在更详细地查看代码之后,这是可以预期的;当您两次运行向量并且仅运行一次数组时。注意:当你resize()使用向量时,你不仅要分配内存,还要运行向量并调用每个成员的构造函数。

稍微重新排列代码,使向量只初始化每个对象一次:

 std::vector<Pixel>  pixels(dimensions * dimensions, Pixel(255,0,0));

现在再次做同样的时间:

g++ -O3 Time.cpp -I
./a.out
UseVector 在 2.216 秒内完成

向量现在的性能只比数组差一点。IMO 这种差异是微不足道的,可能是由一大堆与测试无关的事情引起的。

我还要考虑到您没有正确初始化/销毁UseArrray()方法中的 Pixel
对象,因为没有调用构造函数/析构函数(这对于这个简单的类可能不是问题,但稍微复杂一点(即使用指针或成员)带指针)会导致问题。

2022-06-02