2018年4月8日日曜日

for ベンチマーク

QStringList の for と foreach、range for でのベンチマークです。
forbench.cpp:

#include 
#include 

class ForBenchmark : public QObject
{
    Q_OBJECT

public:
    ForBenchmark() : sizeOfList(1000) {}

    enum class IterationType {
        IndexAt,
        IndexValue,
        IndexMutable,
        Java,
        JavaMutable,
        Stl,
        StlConst,
        Qtforeach,
        QtForeachConst,
        QtForeachConstRef,
#if __cplusplus >= 201103L || (_MSC_VER >= 1700)
        RangeFor,
        RangeForConst,
        RangeForConstRef,
        RangeForAuto,
        RangeForConstAuto,
        RangeForConstAutoRef,
        RangeForAutoRvalue,
        AutoIterator,
        AutoConstIterator,
#endif
    };

private slots:
    void forBenchmark();
    void forBenchmark_data();

private:
    QStringList list;
    const int sizeOfList;
};

Q_DECLARE_METATYPE(ForBenchmark::IterationType)

void ForBenchmark::forBenchmark_data()
{
    QTest::addColumn("type");

    QTest::newRow("Index At") << IterationType::IndexAt;
    QTest::newRow("Index Value") << IterationType::IndexValue;
    QTest::newRow("Index Mutable") << IterationType::IndexMutable;
    QTest::newRow("Java mutable iterator") << IterationType::JavaMutable;
    QTest::newRow("Java iterator") << IterationType::Java;
    QTest::newRow("STL iterator") << IterationType::Stl;
    QTest::newRow("STL const iterator") << IterationType::StlConst;
    QTest::newRow("Qt foreach") << IterationType::Qtforeach;
    QTest::newRow("Qt foreach, const") << IterationType::QtForeachConst;
    QTest::newRow("Qt foreach, const&") << IterationType::QtForeachConstRef;
#if __cplusplus >= 201103L || (_MSC_VER >= 1700)
    QTest::newRow("Range for") << IterationType::RangeFor;
    QTest::newRow("Range for, const") << IterationType::RangeForConst;
    QTest::newRow("Range for, const&") << IterationType::RangeForConstRef;
    QTest::newRow("Range for, auto") << IterationType::RangeForAuto;
    QTest::newRow("Range for, const auto") << IterationType::RangeForConstAuto;
    QTest::newRow("Range for, const auto&") << IterationType::RangeForConstAutoRef;
    QTest::newRow("Range for, auto&&") <<  IterationType::RangeForAutoRvalue;
    QTest::newRow("auto iterator") << IterationType::AutoIterator;
    QTest::newRow("auto const iterator") << IterationType::AutoConstIterator;
#endif

    for (int n = 0; n < sizeOfList; n++) {
        list << QString::number(n);
    }
}

void ForBenchmark::forBenchmark()
{
    QFETCH(IterationType, type);

    int sum = 0;

    switch (type) {
    case IterationType::IndexAt:
        QBENCHMARK {
            for (int i = 0; i < sizeOfList; ++i) {
                sum += list.at(i).size();
            }
        }
        break;
    case IterationType::IndexValue:
        QBENCHMARK {
            for (int i = 0; i < sizeOfList; ++i) {
                sum += list.value(i).size();
            }
        }
        break;
    case IterationType::IndexMutable:
        QBENCHMARK {
            for (int i = 0; i < sizeOfList; ++i) {
                sum += list[i].size();
            }
        }
        break;
    case IterationType::Java: {
        QBENCHMARK {
            QStringListIterator it(list);
            while (it.hasNext())
                sum += it.next().size();
        }
        break;
    }
    case IterationType::JavaMutable: {
        QBENCHMARK {
            QMutableStringListIterator it(list);
            while (it.hasNext())
                sum += it.next().size();
        }
        break;
    }
    case IterationType::Stl: {
        QBENCHMARK {
            const QStringList::iterator end = list.end();
            for (QStringList::iterator it = list.begin(); it != end; ++it) {
                sum += (*it).size();
            }
        }
        break;
    }
    case IterationType::StlConst: {
        QBENCHMARK {
            const QStringList::const_iterator end = list.constEnd();
            for (QStringList::const_iterator it = list.constBegin(); it != end; ++it) {
                sum += (*it).size();
            }
        }
        break;
    }
    case IterationType::Qtforeach:
        QBENCHMARK {
            foreach (QString string, list) {
                sum += string.size();
            }
        }
        break;
    case IterationType::QtForeachConst:
        QBENCHMARK {
            foreach (const QString string, list) {
                sum += string.size();
            }
        }
        break;
    case IterationType::QtForeachConstRef:
        QBENCHMARK {
            foreach (const QString& string, list) {
                sum += string.size();
            }
        }
        break;
#if __cplusplus >= 201103L || (_MSC_VER >= 1700)
    case IterationType::RangeFor:
        QBENCHMARK {
            for (QString string : list) {
                sum += string.size();
            }
        }
        break;
    case IterationType::RangeForConst:
        QBENCHMARK {
            for (const QString string : list) {
                sum += string.size();
            }
        }
        break;
    case IterationType::RangeForConstRef:
        QBENCHMARK {
            for (const QString& string : list) {
                sum += string.size();
            }
        }
        break;
    case IterationType::RangeForAuto:
        QBENCHMARK {
            for (auto string : list) {
                sum += string.size();
            }
        }
        break;
    case IterationType::RangeForConstAuto:
        QBENCHMARK {
            for (const auto string : list) {
                sum += string.size();
            }
        }
        break;
    case IterationType::RangeForConstAutoRef:
        QBENCHMARK {
            for (const auto& string : list) {
                sum += string.size();
            }
        }
        break;
    case IterationType::RangeForAutoRvalue:
        QBENCHMARK {
            for (auto&& it : list) {
                sum += it.size();
            }
        }

        break;
    case IterationType::AutoIterator:
        QBENCHMARK {
            auto end = list.end();
            for (auto it = list.begin(); it != end; ++it) {
                sum += (*it).size();
            }
        }
        break;
    case IterationType::AutoConstIterator: {
        QBENCHMARK {
            auto end = list.constEnd();
            for (auto it = list.constBegin(); it != end; ++it) {
                sum += (*it).size();
            }
        }
    }
        break;
#endif
    }
}

QTEST_MAIN(ForBenchmark)

#include "forbench.moc"
forbench.pro:

QT+=testlib
QT -= gui
CONFIG += release
CONFIG -= app_bundle

TEMPLATE = app
TARGET = forbench

DEPENDPATH += .
INCLUDEPATH += .

SOURCES += forbench.cpp
macOS での実行結果です。
$ ./forbench
********* Start testing of ForBenchmark *********
Config: Using QtTest library 5.10.1, Qt 5.10.1 (x86_64-little_endian-lp64 shared (dynamic) release build; by Clang 8.1.0 (clang-802.0.42) (Apple))
PASS   : ForBenchmark::initTestCase()
PASS   : ForBenchmark::forBenchmark(Index At)
RESULT : ForBenchmark::forBenchmark():"Index At":
     0.000041 msecs per iteration (total: 87, iterations: 2097152)
PASS   : ForBenchmark::forBenchmark(Index Value)
RESULT : ForBenchmark::forBenchmark():"Index Value":
     0.013 msecs per iteration (total: 54, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Index Mutable)
RESULT : ForBenchmark::forBenchmark():"Index Mutable":
     0.00049 msecs per iteration (total: 65, iterations: 131072)
PASS   : ForBenchmark::forBenchmark(Java mutable iterator)
RESULT : ForBenchmark::forBenchmark():"Java mutable iterator":
     0.0131 msecs per iteration (total: 431, iterations: 32768)
PASS   : ForBenchmark::forBenchmark(Java iterator)
RESULT : ForBenchmark::forBenchmark():"Java iterator":
     0.0131 msecs per iteration (total: 215, iterations: 16384)
PASS   : ForBenchmark::forBenchmark(STL iterator)
RESULT : ForBenchmark::forBenchmark():"STL iterator":
     0.0132 msecs per iteration (total: 217, iterations: 16384)
PASS   : ForBenchmark::forBenchmark(STL const iterator)
RESULT : ForBenchmark::forBenchmark():"STL const iterator":
     0.0130 msecs per iteration (total: 107, iterations: 8192)
PASS   : ForBenchmark::forBenchmark(Qt foreach)
RESULT : ForBenchmark::forBenchmark():"Qt foreach":
     0.012 msecs per iteration (total: 53, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Qt foreach, const)
RESULT : ForBenchmark::forBenchmark():"Qt foreach, const":
     0.012 msecs per iteration (total: 53, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Qt foreach, const&)
RESULT : ForBenchmark::forBenchmark():"Qt foreach, const&":
     0.000046 msecs per iteration (total: 97, iterations: 2097152)
PASS   : ForBenchmark::forBenchmark(Range for)
RESULT : ForBenchmark::forBenchmark():"Range for":
     0.012 msecs per iteration (total: 51, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Range for, const)
RESULT : ForBenchmark::forBenchmark():"Range for, const":
     0.012 msecs per iteration (total: 51, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Range for, const&)
RESULT : ForBenchmark::forBenchmark():"Range for, const&":
     0.000042 msecs per iteration (total: 90, iterations: 2097152)
PASS   : ForBenchmark::forBenchmark(Range for, auto)
RESULT : ForBenchmark::forBenchmark():"Range for, auto":
     0.012 msecs per iteration (total: 52, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Range for, const auto)
RESULT : ForBenchmark::forBenchmark():"Range for, const auto":
     0.012 msecs per iteration (total: 52, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Range for, const auto&)
RESULT : ForBenchmark::forBenchmark():"Range for, const auto&":
     0.000042 msecs per iteration (total: 89, iterations: 2097152)
PASS   : ForBenchmark::forBenchmark(Range for, auto&&)
RESULT : ForBenchmark::forBenchmark():"Range for, auto&&":
     0.000042 msecs per iteration (total: 90, iterations: 2097152)
PASS   : ForBenchmark::forBenchmark(auto iterator)
RESULT : ForBenchmark::forBenchmark():"auto iterator":
     0.000041 msecs per iteration (total: 87, iterations: 2097152)
PASS   : ForBenchmark::forBenchmark(auto const iterator)
RESULT : ForBenchmark::forBenchmark():"auto const iterator":
     0.000041 msecs per iteration (total: 88, iterations: 2097152)
PASS   : ForBenchmark::cleanupTestCase()
Totals: 21 passed, 0 failed, 0 skipped, 0 blacklisted, 6451ms
********* Finished testing of ForBenchmark *********
$
Ubuntu での実行結果です。
$ ./forbench 
********* Start testing of ForBenchmark *********
Config: Using QtTest library 5.11.0, Qt 5.11.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 5.3.1 20160406 (Red Hat 5.3.1-6))
PASS   : ForBenchmark::initTestCase()
PASS   : ForBenchmark::forBenchmark(Index At)
RESULT : ForBenchmark::forBenchmark():"Index At":
     0.0000026 msecs per iteration (total: 88, iterations: 33554432)
PASS   : ForBenchmark::forBenchmark(Index Value)
RESULT : ForBenchmark::forBenchmark():"Index Value":
     0.012 msecs per iteration (total: 53, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Index Mutable)
RESULT : ForBenchmark::forBenchmark():"Index Mutable":
     0.00073 msecs per iteration (total: 96, iterations: 131072)
PASS   : ForBenchmark::forBenchmark(Java mutable iterator)
RESULT : ForBenchmark::forBenchmark():"Java mutable iterator":
     0.0000033 msecs per iteration (total: 56, iterations: 16777216)
PASS   : ForBenchmark::forBenchmark(Java iterator)
RESULT : ForBenchmark::forBenchmark():"Java iterator":
     0.000016 msecs per iteration (total: 68, iterations: 4194304)
PASS   : ForBenchmark::forBenchmark(STL iterator)
RESULT : ForBenchmark::forBenchmark():"STL iterator":
     0.0000033 msecs per iteration (total: 56, iterations: 16777216)
PASS   : ForBenchmark::forBenchmark(STL const iterator)
RESULT : ForBenchmark::forBenchmark():"STL const iterator":
     0.0000028 msecs per iteration (total: 97, iterations: 33554432)
PASS   : ForBenchmark::forBenchmark(Qt foreach)
RESULT : ForBenchmark::forBenchmark():"Qt foreach":
     0.012 msecs per iteration (total: 52, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Qt foreach, const)
RESULT : ForBenchmark::forBenchmark():"Qt foreach, const":
     0.012 msecs per iteration (total: 53, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Qt foreach, const&)
RESULT : ForBenchmark::forBenchmark():"Qt foreach, const&":
     0.000015 msecs per iteration (total: 67, iterations: 4194304)
PASS   : ForBenchmark::forBenchmark(Range for)
RESULT : ForBenchmark::forBenchmark():"Range for":
     0.012 msecs per iteration (total: 52, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Range for, const)
RESULT : ForBenchmark::forBenchmark():"Range for, const":
     0.012 msecs per iteration (total: 52, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Range for, const&)
RESULT : ForBenchmark::forBenchmark():"Range for, const&":
     0.0000033 msecs per iteration (total: 57, iterations: 16777216)
PASS   : ForBenchmark::forBenchmark(Range for, auto)
RESULT : ForBenchmark::forBenchmark():"Range for, auto":
     0.013 msecs per iteration (total: 54, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Range for, const auto)
RESULT : ForBenchmark::forBenchmark():"Range for, const auto":
     0.012 msecs per iteration (total: 52, iterations: 4096)
PASS   : ForBenchmark::forBenchmark(Range for, const auto&)
RESULT : ForBenchmark::forBenchmark():"Range for, const auto&":
     0.0000035 msecs per iteration (total: 60, iterations: 16777216)
PASS   : ForBenchmark::forBenchmark(Range for, auto&&)
RESULT : ForBenchmark::forBenchmark():"Range for, auto&&":
     0.0000038 msecs per iteration (total: 64, iterations: 16777216)
PASS   : ForBenchmark::forBenchmark(auto iterator)
RESULT : ForBenchmark::forBenchmark():"auto iterator":
     0.0000041 msecs per iteration (total: 69, iterations: 16777216)
PASS   : ForBenchmark::forBenchmark(auto const iterator)
RESULT : ForBenchmark::forBenchmark():"auto const iterator":
     0.0000026 msecs per iteration (total: 89, iterations: 33554432)
PASS   : ForBenchmark::cleanupTestCase()
Totals: 21 passed, 0 failed, 0 skipped, 0 blacklisted, 5033ms
********* Finished testing of ForBenchmark *********
$


参考情報

Writing a Benchmark

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。