第5章 ベンチマークを書く

この章では、Qt Test を使ってベンチマークを書く方法を説明します。

ベンチマークを書く

ベンチマークを作成するには、テスト関数を QBENCHMARK マクロで拡張します。ベンチマークのテスト関数は通常、セットアップコードと QBENCHMARK マクロで構成されます。このテスト関数はQString::localeAwareCompare() をベンチマークします。

void TestBenchmark::simple()
{
    QString str1 = QLatin1String("This is a test string");
    QString str2 = QLatin1String("This is a test string");

    QCOMPARE(str1.localeAwareCompare(str2), 0);

    QBENCHMARK {
        str1.localeAwareCompare(str2);
    }
}

セットアップは関数の最初に行うことができます。この時点では、クロックは動作していない。QBENCHMARKマクロ内のコードが測定され、正確な測定を行うために数回繰り返される可能性がある。

いくつかのバックエンドが利用可能で、コマンドラインで選択できる。

データ関数

データ関数は、複数のデータ入力を比較するベンチマークを作成するのに便利です。例えば、ロケールを意識した比較と標準的な比較を比較することができます。

void TestBenchmark::multiple_data()
{
    QTest::addColumn<bool>("useLocaleCompare");
    QTest::newRow("locale-aware-compare") << true;
    QTest::newRow("standard-compare") << false;
}

テスト関数は、データを使用してベンチマークを決定します。

void TestBenchmark::multiple()
{
    QFETCH(bool, useLocaleCompare);
    QString str1 = QLatin1String("This is a test string");
    QString str2 = QLatin1String("This is a test string");

    int result;
    if (useLocaleCompare) {
        QBENCHMARK {
            result = str1.localeAwareCompare(str2);
        }
    } else {
        QBENCHMARK {
            result = (str1 == str2);
        }
    }
    Q_UNUSED(result);
}

if (useLocaleCompare) スイッチはオーバーヘッドを測定しないように QBENCHMARK マクロの外に置かれます。各ベンチマークテスト関数はアクティブなQBENCHMARKマクロを1つ持つことができます。

実行ファイルのビルド

テストケースの実行ファイルは CMake あるいは qmake を使ってビルドします。

CMake によるビルド

CMakeLists.txt ファイルでビルド設定を行います:

# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

cmake_minimum_required(VERSION 3.16)
project(tutorial5 LANGUAGES CXX)

find_package(Qt6 REQUIRED COMPONENTS Core Gui Test Widgets)

qt_standard_project_setup()

qt_add_executable(tutorial5
    benchmarking.cpp
)

set_target_properties(tutorial5 PROPERTIES
    WIN32_EXECUTABLE TRUE
    MACOSX_BUNDLE TRUE
)

target_link_libraries(tutorial5 PRIVATE
    Qt6::Core
    Qt6::Gui
    Qt6::Test
    Qt6::Widgets
)

install(TARGETS tutorial5
    BUNDLE  DESTINATION .
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

qt_generate_deploy_app_script(
    TARGET tutorial5
    OUTPUT_SCRIPT deploy_script
    NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})

次に、コマンドラインからcmake を実行するか、Qt-prefix/<version>/<platform>/bin/qt-cmake にあるqt-cmake 便利スクリプトを使用します:

<Qt-prefix>/<version>/<platform>/bin/qt-cmake <source-dir> <build-dir> -G Ninja

次に、お好みのジェネレーター・ツールを実行して実行ファイルをビルドします。ここではNinjaを使っています:

ninja

qmakeでビルドする

.pro ファイルでビルド設定を行います:

QT += widgets testlib

SOURCES = benchmarking.cpp

# install
target.path = $$[QT_INSTALL_EXAMPLES]/qtestlib/tutorial5
INSTALLS += target

次にqmake を実行し、最後にmake を実行して実行ファイルをビルドします:

qmake
make

実行ファイルの実行

出来上がった実行ファイルを実行すると、以下のような出力が得られるはずだ:

********* Start testing of TestBenchmark *********
Config: Using QtTest library %VERSION%, Qt %VERSION%
PASS   : TestBenchmark::initTestCase()
PASS   : TestBenchmark::simple()
RESULT : TestBenchmark::simple():
     0.00030 msecs per iteration (total: 79, iterations: 262144)
PASS   : TestBenchmark::multiple(locale-aware-compare)
RESULT : TestBenchmark::multiple():"locale-aware-compare":
     0.00029 msecs per iteration (total: 78, iterations: 262144)
.....
PASS   : TestBenchmark::series(locale-aware-compare:8001)
RESULT : TestBenchmark::series():"locale-aware-compare:8001":
     0.039 msecs per iteration (total: 81, iterations: 2048)
Totals: 15 passed, 0 failed, 0 skipped, 0 blacklisted, 3971ms
********* Finished testing of TestBenchmark *********

本書に含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。