使用Qt中的容器给C++开发带来很大的便利,而且QVector和QMap等容器扩展的一些成员函数也是很方便的。但是Qt的这些容器和STL库的容器比,效率到底怎么样?我就写了几个简单的遍历的例子,测试了QVector、vector等容器的那些方法效率更高。
测试环境:
系统:windows 10
编译器:MingGW mingw5.3.0
Qt版本:5.9.7
硬件:i7 8代,16G内存
一. 测试QVector和vector的各种遍历的方法:
void CompareQVectorAndVectorTraverse()
{
int size = 100000000;
QVector qv(size, 1);
vector v(size, 1);
printf("vector size: %d\n", size);
// const_iterator比较
QVector::ConstIterator cqvit;
int sum = 0;
qint64 start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for( cqvit = qv.constBegin(); cqvit != qv.constEnd(); ++cqvit)
{
sum += *cqvit;
}
qint64 end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "qvector ConstIterator %dms\n", end - start );
printf("%d\n", sum);
QVector::const_iterator cqvit2;
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for( cqvit2 = qv.cbegin(); cqvit2 != qv.cend(); ++cqvit2)
{
sum += *cqvit2;
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "qvector const_iterator %dms\n", end - start );
printf("%d\n", sum);
vector::const_iterator cvit;
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for( cvit = v.cbegin(); cvit != v.cend(); ++cvit )
{
sum += *cvit;
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "stl vector const_iterator %dms\n", end - start );
printf("%d\n", sum);
// iterator比较
QVector::iterator it;
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for( it = qv.begin(); it != qv.end(); ++it)
{
sum += *it;
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "qvector iterator %dms\n", end - start );
printf("%d\n", sum);
vector::iterator vit;
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for( vit = v.begin(); vit != v.end(); ++vit )
{
sum += *vit;
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "stl vector iterator %dms\n", end - start );
printf("%d\n", sum);
//[]比较
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for( int i = 0; i < qv.size(); ++i)
{
sum += qv[i];
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "QVector [] %dms\n", end - start );
printf("%d\n", sum);
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for( int i = 0; i < v.size(); ++i)
{
sum += v[i];
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "stl vector [] %dms\n", end - start );
printf("%d\n", sum);
//.data()比较
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
int *data = qv.data();
for( int i = 0; i < qv.size(); ++i)
{
sum += data[i];
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "QVector .data() %dms\n", end - start );
printf("%d\n", sum);
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
data = v.data();
for( int i = 0; i < v.size(); ++i)
{
sum += data[i];
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "stl vector .data() %dms\n", end - start );
printf("%d\n", sum);
//:比较
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for( int val : qv )
{
sum += val;
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "QVector : %dms\n", end - start );
printf("%d\n", sum);
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for( int val : v)
{
sum += val;
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "stl vector : %dms\n", end - start );
printf("%d\n", sum);
}
运行结果:
vector size: 100000000
qvector ConstIterator 1252ms
100000000
qvector const_iterator 1254ms
100000000
stl vector const_iterator 1318ms
100000000
qvector iterator 4233ms
100000000
stl vector iterator 1319ms
100000000
QVector [] 4862ms
100000000
stl vector [] 456ms
100000000
QVector .data() 275ms
100000000
stl vector .data() 296ms
100000000
QVector : 187ms
100000000
stl vector : 870ms
100000000
二. 测试QMap和map的各种遍历的方法:
void CompareQMapAndMapTraverse()
{
int size = 1000000;
qint64 sum = 0;
qint64 start, end;
map m;
char *tmps = new char[10];
for( int i = 0; i < size; ++i )
{
sprintf( tmps, "%s%d", "a", i);
m.insert( make_pair(tmps, i) );
}
QMap qm(m);
printf("map size: %d\n", m.size());
//iterator比较
QMap::iterator qmit;
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for(qmit = qm.begin(); qmit != qm.end(); ++qmit )
{
sum += qmit.value();
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "QMap iterator %dms\n", end - start );
printf("%d\n", sum);
map::iterator mit;
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for( mit = m.begin(); mit != m.end(); ++mit )
{
sum += mit->second;
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "stl::map iterator %dms\n", end - start );
printf("%d\n", sum);
//const_iterator比较
QMap::const_iterator cqmit;
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for(cqmit = qm.cbegin(); cqmit != qm.cend(); ++cqmit )
{
sum += cqmit.value();
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "QMap const_iterator %dms\n", end - start );
printf("%d\n", sum);
map::const_iterator cmit;
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for( cmit = m.cbegin(); cmit != m.cend(); ++cmit )
{
sum += cmit->second;
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "stl::map const_iterator %dms\n", end - start );
printf("%d\n", sum);
QMap::key_iterator qmkeyit;
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for( qmkeyit = qm.keyBegin(); qmkeyit != qm.keyEnd(); ++qmkeyit )
{
sum += qm[*qmkeyit];
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "QMap key_iterator %dms\n", end - start );
printf("%d\n", sum);
sum = 0;
start = QDateTime::currentDateTime().toMSecsSinceEpoch();
for( string k : qm.keys() )
{
sum += qm[k];
}
end = QDateTime::currentDateTime().toMSecsSinceEpoch();
printf( "QMap .keys %dms\n", end - start );
printf("%d\n", sum);
}
运行结果:
map size: 1000000
QMap iterator 49ms
1783293664
stl::map iterator 38ms
1783293664
QMap const_iterator 33ms
1783293664
stl::map const_iterator 38ms
1783293664
QMap key_iterator 407ms
1783293664
QMap .keys 551ms
1783293664
基本和预期的结果差不多,得出结果是QVector最好用for(T &t : qvT)方式。QMap用iterator比较快,而且const_iterator和iterator差不多。