我一直认为这std::vector是“作为数组实现”的普遍智慧,等等等等。今天下楼测试了一下,好像不是这样:
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可能会慢几纳秒”的评论。
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。
#define _SECURE_SCL 0
UseVector
使用以下内容:
g++ -O3 Time.cpp -I ./a.out UseArray 在 2.196 秒内完成 UseVector 在 4.412 秒内 完成 UseVectorPushBack在 8.017 秒内完成 整个事情在 14.626 秒内完成
所以数组的速度是向量的两倍。
但是 在更详细地查看代码之后,这是可以预期的;当您两次运行向量并且仅运行一次数组时。注意:当你resize()使用向量时,你不仅要分配内存,还要运行向量并调用每个成员的构造函数。
resize()
稍微重新排列代码,使向量只初始化每个对象一次:
std::vector<Pixel> pixels(dimensions * dimensions, Pixel(255,0,0));
现在再次做同样的时间:
g++ -O3 Time.cpp -I ./a.out UseVector 在 2.216 秒内完成
向量现在的性能只比数组差一点。IMO 这种差异是微不足道的,可能是由一大堆与测试无关的事情引起的。
我还要考虑到您没有正确初始化/销毁UseArrray()方法中的 Pixel 对象,因为没有调用构造函数/析构函数(这对于这个简单的类可能不是问题,但稍微复杂一点(即使用指针或成员)带指针)会导致问题。
UseArrray()