The use of containers in Qt brings great convenience to C++ development, and some member functions extended by containers such as QVector and QMap are also very convenient. But how efficient are Qt's containers compared with STL's? I've just written a few simple traversal examples to test the more efficient methods of containers like QVector and vector.
Test environment:
System: windows 10
Compiler: MingGW mingw5.3.0
Qt version: 5.9.7
Hardware: i7 8, 16G memory
I. Testing various traversal methods of QVector and vector:
void CompareQVectorAndVectorTraverse() { int size = 100000000; QVector<int> qv(size, 1); vector<int> v(size, 1); printf("vector size: %d\n", size); // const_iterator comparison QVector<int>::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<int>::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<int>::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 comparison QVector<int>::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<int>::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); //[comparison] 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() comparison 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); //Comparison 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); }
Operation results:
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
2. Testing various traversal methods of QMap and map:
void CompareQMapAndMapTraverse() { int size = 1000000; qint64 sum = 0; qint64 start, end; map<string, int> 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<string, int> qm(m); printf("map size: %d\n", m.size()); //iterator comparison QMap<string, int>::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<string, int>::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 comparison QMap<string, int>::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<string, int>::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<string, int>::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); }
Operation results:
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
The results are basically the same as expected. The result is that QVector is best used for (T&t: qvT) mode. QMap uses iterator faster, and const_iterator is similar to iterator.