在编写处理相对大量元素(~100k)的程序时,我注意到 std :: list 和 QList 之间存在奇怪的区别。 起初我使用了 std :: vector ,效果很好。但是因为程序经常需要在向量中的随机位置插入元素,所以当迭代器处于所需位置时,我切换到 std :: list ,它有一个恒定的插入时间。 / p>
问题是,std :: list的执行方式比使用insert()和push_back()方法的std :: vector更差。 测量为将100个连续元素添加到具有100k元素的列表中:
请注意,插入元素的时间不包括使用迭代器到达位置的时间。
我知道列表的性能问题,因为列表导致了缓存缺失,但这似乎远远超出了缓存未命中的限制。 插入元素(具有5个常量长度变量的简单结构)的时间也随着列表的大小而增加。即使获得列表大小的操作也需要更多时间。 这与列表的两个操作保证的时间复杂性形成鲜明对比:常量。
请参阅:Here
出于好奇,从 std :: list 更改为 QList 和中提琴:插入时间是恒定的,介于0ms和1ms之间。
以下是用于衡量插入时间的代码。
两个时间点之间不执行任何其他操作:错误:使用size()方法
的std ::列表:
QTime time;
time.start();
for (int a = 1; a <= lineChange; a++)
{
listData.insert(listIterator, newElement);
}
int elapsed = time.restart();
qDebug() << "elapsed: " << elapsed << "ms";
结果:已过去:662毫秒
的QList:
QTime time;
time.start();
for (int a = 1; a <= lineChange; a++)
{
QListData.insert(iteratorPos, newElement);
position++;
}
int elapsed = time.restart();
qDebug() << "elapsed: " << elapsed << "ms";
结果:已过去:1毫秒
的std ::矢量:
QTime time;
time.start();
for (int a = 1; a <= lineChange; a++)
{
vectorData.insert(vectorIterator, newElement);
/*update of the iterator when it was
invalidated due to resize of the vector*/
}
int elapsed = time.restart();
qDebug() << "elapsed: " << elapsed << "ms";
结果:已过去:27毫秒
那么,为什么QList和std :: list之间存在如此巨大的差异? 或者更好:为什么 std :: list 的性能如此糟糕?
作为附带信息:我在Linux(Mint)下使用带有gcc的QtEditor,标志设置为c ++ 11
编辑:
数据类型和声明:
typedef struct TOKELEMENT {
unsigned int column;
unsigned int lenght;
unsigned int tType;
std::string value;
} tokElement;
// the three lists
std::vector<okElement> vectorData;
std::list<tokElement> listData;
QList<tokElement> QListData;
tokElement newElement;
unsigned int iteratorPos;
std::vector<std::vector<tokElement> >::iterator vectorIterator;
std::list<std::vector<tokElement> >::iterator listIterator;
//lineChange is an unsigned int, given as function parameter
unsigned int lineChange;
答案 0 :(得分:3)
与我在问题中提到的内容(对我的耻辱)相反,我在 for-loop 中另外检查了 std :: list 的大小确定是否在列表中使用insert()或push_back()。 由于该函数不具有O(1)但O(n)的时间复杂度,因此这大大减慢了整个插入。感谢 Leeor 指出这一点。
将此检查移出 for-loop 之后,std :: list按照预期执行,甚至比QList更快。