qtにおけるQVectorとvectorおよびQMapとmapの遍歴性能の比較

7881 ワード

Qtのコンテナを使用することはC++の開発に大きな便利さをもたらし,QVectorやQMapなどのコンテナ拡張のメンバー関数も便利である.しかしQtのこれらの容器とSTLライブラリの容器の比、効率はいったいどうですか?QVector,vectorなどの容器をテストする方法の効率が高い簡単な遍歴例をいくつか書きました.
テスト環境:
システム:windows 10
コンパイラ:MingGW mingw 5.3.0
Qtバージョン:5.9.7
ハードウェア:i 7 8世代、16 Gメモリ
一.QVectorとvectorの様々な遍歴をテストする方法:
void CompareQVectorAndVectorTraverse()
{
    int size = 100000000;
    QVector qv(size, 1);
    vector v(size, 1);

    printf("vector size: %d
", 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
", end - start ); printf("%d
", 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
", end - start ); printf("%d
", 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
", end - start ); printf("%d
", 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
", end - start ); printf("%d
", 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
", end - start ); printf("%d
", 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
", end - start ); printf("%d
", 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
", end - start ); printf("%d
", 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
", end - start ); printf("%d
", 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
", end - start ); printf("%d
", sum); //: sum = 0; start = QDateTime::currentDateTime().toMSecsSinceEpoch(); for( int val : qv ) { sum += val; } end = QDateTime::currentDateTime().toMSecsSinceEpoch(); printf( "QVector : %dms
", end - start ); printf("%d
", sum); sum = 0; start = QDateTime::currentDateTime().toMSecsSinceEpoch(); for( int val : v) { sum += val; } end = QDateTime::currentDateTime().toMSecsSinceEpoch(); printf( "stl vector : %dms
", end - start ); printf("%d
", 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
", 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
", end - start ); printf("%d
", 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
", end - start ); printf("%d
", 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
", end - start ); printf("%d
", 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
", end - start ); printf("%d
", 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
", end - start ); printf("%d
", sum); sum = 0; start = QDateTime::currentDateTime().toMSecsSinceEpoch(); for( string k : qm.keys() ) { sum += qm[k]; } end = QDateTime::currentDateTime().toMSecsSinceEpoch(); printf( "QMap .keys %dms
", end - start ); printf("%d
", 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の差は多くありません.