我已经有了一个用另一个数组中的值填充某些数组的过程。 它看起来类似于下面的代码:std :: vector :: clear()在代码重构后需要更多时间
// Point 0
ptrlistVector.clear();
// Point 1
ptrlistVector.resize(50);
const size_t s = ptrlistVector.size();
// Point 2
for (ObjectList::iterator j = objList.begin(); j != objList.end(); ++j)
{
for (UINT i = 0; i < s; ++i)
{
ptrlistVector[i].push_back(&(*j));
}
}
// Point 3
其实,有在“的push_back”行复杂的代码 - 我把不同的值的列表。这些值取决于某些条件。
宣言S和定义:
typedef std::list<void*> ObjectPtrList;
typedef std::vector<ObjectPtrList> PtrListVector;
typedef std::list<std::string> ObjectList;
ObjectList objList;
PtrListVector ptrlistVector;
予测量的时间点之间,在平均号码点1-0花费0.02秒和点3-2花费0.05秒。 我试图重构循环,发现一些奇怪的行为。 我用以下替换上面的循环:
for (UINT i = 0; i < s; ++i)
{
for (ObjectList::iterator j = objList.begin(); j != objList.end(); ++j)
{
ptrlistVector[i].push_back(&(*j));
}
}
之后,时间更改。第3-2点需要0.035秒,但clear()调用(点1-0)现在需要0.45(!!!),远远大于前一次。
我使用MSVC 10.0,调试和发布模式下的结果大致相同。在发布模式中,时间差异并不那么显着,但无论如何,第二个时间更长。
任何人都可以请解释我为什么clear()调用需要更多的时间后,我改变了循环?
下面的代码是我用于性能测试的控制台应用程序。
#include "stdafx.h"
#include <windows.h>
#include <vector>
#include <list>
#include <cstdio>
#include <cassert>
#include <string>
int _tmain(int argc, _TCHAR* argv[])
{
typedef std::list<void*> ObjectPtrList;
typedef std::vector<ObjectPtrList> PtrListVector;
typedef std::list<std::string> ObjectList;
ObjectList objList;
objList.insert(objList.begin(), 500, std::string());
PtrListVector ptrlistVector;
LARGE_INTEGER __counters[10];
double __totals[10] = { 0 };
UINT __counter = 0;
BOOL bRes;
LARGE_INTEGER __freq;
bRes = QueryPerformanceFrequency(&__freq);
assert(bRes);
for (int k = 0; k < 500; ++k)
{
// Point 0
bRes = QueryPerformanceCounter(&__counters[0]);
ptrlistVector.clear();
// Point 1
bRes = QueryPerformanceCounter(&__counters[1]);
ptrlistVector.resize(50);
const size_t s = ptrlistVector.size();
// Point 2
bRes = QueryPerformanceCounter(&__counters[2]);
/*
// original
for (ObjectList::iterator j = objList.begin(); j != objList.end(); ++j)
{
for (UINT i = 0; i < s; ++i)
{
ptrlistVector[i].push_back(&(*j));
}
}
/*/
for (UINT i = 0; i < s; ++i) // refactored
{
for (ObjectList::iterator j = objList.begin(); j != objList.end(); ++j)
{
ptrlistVector[i].push_back(&(*j));
}
}
//*/
// Point 3
bRes = QueryPerformanceCounter(&__counters[3]);
__counter += 1;
__totals[1] += 1.0 * (__counters[1].QuadPart - __counters[0].QuadPart)/__freq.QuadPart;
__totals[2] += 1.0 * (__counters[2].QuadPart - __counters[1].QuadPart)/__freq.QuadPart;
__totals[3] += 1.0 * (__counters[3].QuadPart - __counters[2].QuadPart)/__freq.QuadPart;
__totals[4] += 1.0 * (__counters[3].QuadPart - __counters[0].QuadPart)/__freq.QuadPart;
printf("%s: %.4f %.4f %.4f = %.4f\n",
__FUNCTION__,
__totals[1]/__counter,
__totals[2]/__counter,
__totals[3]/__counter,
__totals[4]/__counter);
}
return 0;
}
在循环前调用'reserve'并添加元素的数量,'clear'应该更快。 – 2012-02-23 15:32:24
你确定'ptrlistVector.resize(50)'?它向你的矢量添加50个构造不好的对象(你的情况只是空指针),然后你添加更多的项目。可疑一点。 – 2012-02-23 15:42:07
安迪,是的,我确定。我不测量调整大小的电话。而且我不再向项目中添加项目,我将项目添加到空白列表中,这是向量的元素。 – Rom098 2012-02-23 15:53:00