/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ****************************************************************************/ #include #include #include #include namespace { Utils::SmallStringView createText(int size) { auto text = new char[size + 1]; std::fill(text, text + size, 'x'); text[size] = 0; return Utils::SmallStringView(text, size); } void CreateSmallStringLiteral(benchmark::State& state) { while (state.KeepRunning()) constexpr auto string = Utils::SmallStringLiteral("very very very long long long text"); } BENCHMARK(CreateSmallStringLiteral); void CreateNullSmallString(benchmark::State& state) { while (state.KeepRunning()) auto string = Utils::SmallString(); } BENCHMARK(CreateNullSmallString); void CreateSmallStringFromLiteral(benchmark::State& state) { while (state.KeepRunning()) auto string = Utils::SmallString("very very very long long long text"); } BENCHMARK(CreateSmallStringFromLiteral); void CreateSmallString(benchmark::State& state) { auto text = createText(state.range(0)); while (state.KeepRunning()) auto string = Utils::SmallString(text.data(), state.range(0)); } BENCHMARK(CreateSmallString)->Range(0, 1024); void CreateQByteArray(benchmark::State& state) { auto text = createText(state.range(0)); while (state.KeepRunning()) QByteArray foo(text.data(), state.range(0)); } BENCHMARK(CreateQByteArray)->Range(0, 1024); void CreateQString(benchmark::State& state) { auto text = createText(state.range(0)); while (state.KeepRunning()) auto string = QString::fromUtf8(text.data(), state.range(0)); } BENCHMARK(CreateQString)->Range(0, 1024); void SmallStringAppend(benchmark::State& state) { auto text = createText(state.range(1)); while (state.KeepRunning()) { auto string = Utils::SmallString(); for (int i = 0; i < state.range(0); ++i) string.append(text); } } BENCHMARK(SmallStringAppend)->RangePair(1, 64, 1, 4096); void QByteArrayAppend(benchmark::State& state) { auto text = createText(state.range(1)); while (state.KeepRunning()) { auto string = QByteArray(); for (int i = 0; i < state.range(0); ++i) string.append(text.data(), text.size()); } } BENCHMARK(QByteArrayAppend)->RangePair(1, 64, 1, 4096); void CompareCString(benchmark::State& state) { Utils::SmallString text("myFunctionIsQuiteLong"); while (state.KeepRunning()) benchmark::DoNotOptimize(text == "staticMetaObject"); } BENCHMARK(CompareCString); void CompareString(benchmark::State& state) { Utils::SmallString text("myFunctionIsQuiteLong"); while (state.KeepRunning()) benchmark::DoNotOptimize(text == Utils::SmallString("staticMetaObject")); } BENCHMARK(CompareString); void CompareStringView(benchmark::State& state) { Utils::SmallString text("myFunctionIsQuiteLong"); while (state.KeepRunning()) benchmark::DoNotOptimize(text == Utils::SmallStringView("staticMetaObject")); } BENCHMARK(CompareStringView); void CompareCStringPointer(benchmark::State& state) { Utils::SmallString text("myFunctionIsQuiteLong"); const char *cStringText = "staticMetaObject"; while (state.KeepRunning()) benchmark::DoNotOptimize(text == cStringText); } BENCHMARK(CompareCStringPointer); void StartsWith(benchmark::State& state) { Utils::SmallString text("myFunctionIsQuiteLong"); while (state.KeepRunning()) benchmark::DoNotOptimize(text.startsWith("qt_")); } BENCHMARK(StartsWith); void ShortSize(benchmark::State& state) { Utils::SmallString text("myFunctionIsQuiteLong"); while (state.KeepRunning()) benchmark::DoNotOptimize(text.size()); } BENCHMARK(ShortSize); void LongSize(benchmark::State& state) { Utils::SmallString text("myFunctionIsQuiteLong"); while (state.KeepRunning()) benchmark::DoNotOptimize(text.size()); } BENCHMARK(LongSize); void Size(benchmark::State& state) { Utils::SmallString text("myFunctionIsMUCHMUCHMUCHMUCHMUCHLonger"); while (state.KeepRunning()) benchmark::DoNotOptimize(text.size()); } BENCHMARK(LongSize); void generateRandomString(char *data, const int length) { static const char alphaNumericData[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"; for (int i = 0; i < length; ++i) { data[i] = alphaNumericData[std::rand() % (sizeof(alphaNumericData) - 1)]; } } uint entryCount=100000; QByteArray generateRandomQByteArray() { QByteArray text; text.resize(20); generateRandomString(text.data(), text.size()); return text; } void Collection_CreateQByteArrays(benchmark::State& state) { while (state.KeepRunning()) { QVector values; values.reserve(entryCount); for (int i = 0; i < entryCount; i++) values.append(generateRandomQByteArray()); } } BENCHMARK(Collection_CreateQByteArrays); void Collection_SortQByteArrays(benchmark::State& state) { while (state.KeepRunning()) { state.PauseTiming(); QVector values; values.reserve(entryCount); for (int i = 0; i < entryCount; i++) values.append(generateRandomQByteArray()); state.ResumeTiming(); std::sort(values.begin(), values.end()); } } BENCHMARK(Collection_SortQByteArrays); void Collection_FilterQByteArrays(benchmark::State& state) { while (state.KeepRunning()) { state.PauseTiming(); QVector values; values.reserve(entryCount); QVector filteredValues; filteredValues.reserve(entryCount); for (int i = 0; i < entryCount; i++) values.append(generateRandomQByteArray()); auto startsWithA = [] (const QByteArray &byteArray) { return byteArray.startsWith('a'); }; state.ResumeTiming(); std::copy_if(std::make_move_iterator(values.begin()), std::make_move_iterator(values.end()), std::back_inserter(filteredValues), startsWithA); } } BENCHMARK(Collection_FilterQByteArrays); Utils::SmallString generateRandomSmallString(int size = 20) { Utils::SmallString text; text.resize(size); generateRandomString(text.data(), text.size()); return text; } void Collection_CreateSmallStrings(benchmark::State& state) { while (state.KeepRunning()) { Utils::SmallStringVector values; values.reserve(entryCount); for (int i = 0; i < entryCount; i++) values.push_back(generateRandomSmallString()); } } BENCHMARK(Collection_CreateSmallStrings); void Collection_SortSmallStrings(benchmark::State& state) { while (state.KeepRunning()) { state.PauseTiming(); Utils::SmallStringVector values; values.reserve(entryCount); for (int i = 0; i < entryCount; i++) values.push_back(generateRandomSmallString()); state.ResumeTiming(); std::sort(values.begin(), values.end()); } } BENCHMARK(Collection_SortSmallStrings); void Collection_FilterSmallStrings(benchmark::State& state) { while (state.KeepRunning()) { state.PauseTiming(); Utils::SmallStringVector values; values.reserve(entryCount); Utils::SmallStringVector filteredValues; filteredValues.reserve(entryCount); for (int i = 0; i < entryCount; i++) values.push_back(generateRandomSmallString()); auto startsWithA = [] (const Utils::SmallString &byteArray) { return byteArray.startsWith('a'); }; state.ResumeTiming(); std::copy_if(std::make_move_iterator(values.begin()), std::make_move_iterator(values.end()), std::back_inserter(filteredValues), startsWithA); } } BENCHMARK(Collection_FilterSmallStrings); void IterateOver(benchmark::State& state) { Utils::SmallString text = generateRandomSmallString(30); auto begin = std::next(text.begin(), state.range(0)); auto end = std::next(text.begin(), state.range(1)); while (state.KeepRunning()) { std::for_each(begin, end, [] (char x) { benchmark::DoNotOptimize(x); }); } } BENCHMARK(IterateOver)->ArgPair(0, 8) ->ArgPair(8, 16) ->ArgPair(16, 24) ->ArgPair(24, 31) ->ArgPair(0, 8) ->ArgPair(0, 16) ->ArgPair(0, 24) ->ArgPair(0, 31); //void StringLiteralSize(benchmark::State& state) { // constexpr Utils::SmallStringLiteral text("myFunctionIsQuiteLong"); // while (state.KeepRunning()) { // constexpr auto size = text.size(); // internal compile error // benchmark::DoNotOptimize(size); // } //} //BENCHMARK(StringLiteralSize); }