一切都取决于你如何实现你的算法。std::vector
是这样一个通用的容器概念,它给了我们灵活性,但让我们有自由和责任去刻意构建算法的实现。我们将观察到的大部分效率开销std::vector
来自于复制。std::vector
提供了一个构造函数,可以让你用值 X 初始化 N 个元素,当你使用它时,向量和数组一样快。
我做了一个测试与这里std::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);
}
}
void UseVectorCtor()
{
TestTimer t("UseConstructor");
for(int i = 0; i < 1000; ++i)
{
int dimension = 999;
std::vector<Pixel> pixels(dimension * dimension, Pixel(255, 0, 0));
}
}
int main()
{
TestTimer t1("The whole thing");
UseArray();
UseVector();
UseVectorCtor();
UseVectorPushBack();
return 0;
}
以下是结果(在 Ubuntu amd64 上使用 g++ -O3 编译):
UseArray 在0.325秒
内完成 UseVector 在 1.23 秒内
完成 UseConstructor 在 0.866 秒
内完成 UseVectorPushBack 在 8.987 秒内完成
整个事情在 11.411 秒内完成
显然push_back
这里不是一个好的选择,使用构造函数仍然比数组慢 2 倍。现在,为 Pixel 提供空副本 Tor:
Pixel(const Pixel&) {}
给我们以下结果:
UseArray 在0.331秒
内完成 UseVector 在 0.306 秒内
完成 UseConstructor 在 0 秒内
完成 UseVectorPushBack 在 2.714 秒内完成
整个事情在 3.352 秒内完成
总而言之:重新考虑您的算法,否则,可能会求助于 New[]/Delete[] 周围的自定义包装器。在任何情况下,STL 实现并没有因为某些未知原因而变慢,它只是按照您的要求执行;希望你知道得更好。在您刚开始使用向量的情况下,它们的行为可能会令人惊讶,例如以下代码:
class U{
int i_;
public:
U(){}
U(int i) : i_(i) {cout << "consting " << i_ << endl;}
U(const U& ot) : i_(ot.i_) {cout << "copying " << i_ << endl;}
};
int main(int argc, char** argv)
{
std::vector<U> arr(2,U(3));
arr.resize(4);
return 0;
}
结果:
构造 3
复制 3
复制 3
复制 548789016
复制 548789016
复制 3
复制 3