File indexing completed on 2024-05-12 04:40:57

0001 /*
0002     SPDX-FileCopyrightText: Milian Wolff <mail@milianw.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include "bench_quickopen.h"
0008 
0009 #include <interfaces/icore.h>
0010 #include <interfaces/iprojectcontroller.h>
0011 #include <interfaces/idocumentcontroller.h>
0012 #include <interfaces/iproject.h>
0013 #include <project/projectutils.h>
0014 #include <tests/testhelpers.h>
0015 
0016 #include <QIcon>
0017 #include <QTest>
0018 #include <QStandardPaths>
0019 #include <QVector>
0020 
0021 #include <utility>
0022 
0023 QTEST_MAIN(BenchQuickOpen)
0024 
0025 using namespace KDevelop;
0026 
0027 namespace
0028 {
0029 QUrl openAnyDocument(IProject* project)
0030 {
0031     auto url = project->fileSet().begin()->toUrl();
0032     QVERIFY_RETURN(ICore::self()->documentController()->openDocument(url), url);
0033     return url;
0034 }
0035 }
0036 
0037 BenchQuickOpen::BenchQuickOpen(QObject* parent)
0038     : QuickOpenTestBase(Core::Default, parent)
0039 {
0040     QStandardPaths::setTestModeEnabled(true);
0041 }
0042 
0043 void BenchQuickOpen::getData()
0044 {
0045     QTest::addColumn<int>("files");
0046     QTest::addColumn<QString>("filter");
0047 
0048     for (auto files : { 1000, 10000 }) {
0049         for (auto pattern : { "", "bar", "1", "f/b" }) {
0050             QTest::addRow("%5d-%3s", files, pattern) << files << QString::fromUtf8(pattern);
0051         }
0052     }
0053 }
0054 
0055 void BenchQuickOpen::getAddRemoveData()
0056 {
0057     QTest::addColumn<int>("files");
0058 
0059     for (auto files : { 1000, 10000 })
0060         QTest::addRow("%d", files) << files;
0061 }
0062 
0063 void BenchQuickOpen::benchProjectFile_swap()
0064 {
0065     QScopedPointer<TestProject> project(getProjectWithFiles(2));
0066     QVector<ProjectFile> projectFiles;
0067     KDevelop::forEachFile(project->projectItem(), [&projectFiles](ProjectFileItem* fileItem) {
0068         projectFiles.push_back(ProjectFile{fileItem});
0069     });
0070     QCOMPARE(projectFiles.size(), 2);
0071 
0072     ProjectFile a = projectFiles.at(0);
0073     ProjectFile b = projectFiles.at(1);
0074     QBENCHMARK {
0075         using std::swap;
0076         swap(a, b);
0077     }
0078 }
0079 
0080 void BenchQuickOpen::benchProjectFileFilter_addRemoveProject()
0081 {
0082     QFETCH(int, files);
0083 
0084     ProjectFileDataProvider provider;
0085     QScopedPointer<TestProject> project(getProjectWithFiles(files));
0086 
0087     QBENCHMARK {
0088         projectController->addProject(project.data());
0089         projectController->takeProject(project.data());
0090     }
0091 }
0092 
0093 void BenchQuickOpen::benchProjectFileFilter_addRemoveProject_data()
0094 {
0095     getAddRemoveData();
0096 }
0097 
0098 void BenchQuickOpen::benchProjectFileFilter_addRemoveProjects()
0099 {
0100     QFETCH(int, files);
0101 
0102     ProjectFileDataProvider provider;
0103 
0104     QTemporaryDir dir;
0105     QScopedPointer<TestProject> projectA(getProjectWithFiles(files, Path(dir.filePath("a_project_dir/"))));
0106     QScopedPointer<TestProject> projectB(getProjectWithFiles(files, Path(dir.filePath("b_project_dir/"))));
0107     QScopedPointer<TestProject> projectC(getProjectWithFiles(files, Path(dir.filePath("c_project_dir/"))));
0108 
0109     openAnyDocument(projectA.data());
0110 
0111     QBENCHMARK {
0112         projectController->addProject(projectA.data());
0113         projectController->addProject(projectB.data());
0114         projectController->addProject(projectC.data());
0115 
0116         projectController->takeProject(projectC.data());
0117         projectController->takeProject(projectB.data());
0118         projectController->takeProject(projectA.data());
0119     }
0120 }
0121 
0122 void BenchQuickOpen::benchProjectFileFilter_addRemoveProjects_data()
0123 {
0124     getAddRemoveData();
0125 }
0126 
0127 void BenchQuickOpen::benchProjectFileFilter_reset()
0128 {
0129     QFETCH(int, files);
0130     QFETCH(QString, filter);
0131 
0132     ProjectFileDataProvider provider;
0133     TestProject* project = getProjectWithFiles(files);
0134     provider.setFilterText(filter);
0135 
0136     projectController->addProject(project);
0137     openAnyDocument(project);
0138 
0139     // don't use QBENCHMARK directly as the code below is too fast
0140     // and then QBENCHMARK runs the setup code above multiple times which is overly slow
0141     QBENCHMARK_ONCE
0142     {
0143         for (int i = 0; i < 1000; ++i) {
0144             provider.reset();
0145         }
0146     }
0147 }
0148 
0149 void BenchQuickOpen::benchProjectFileFilter_reset_data()
0150 {
0151     getData();
0152 }
0153 
0154 void BenchQuickOpen::benchProjectFileFilter_setFilter()
0155 {
0156     QFETCH(int, files);
0157     QFETCH(QString, filter);
0158 
0159     ProjectFileDataProvider provider;
0160     TestProject* project = getProjectWithFiles(files);
0161 
0162     projectController->addProject(project);
0163 
0164     provider.reset();
0165 
0166     QBENCHMARK {
0167         provider.setFilterText(filter);
0168         provider.setFilterText(QString());
0169     }
0170 }
0171 
0172 void BenchQuickOpen::benchProjectFileFilter_setFilter_data()
0173 {
0174     getData();
0175 }
0176 
0177 void BenchQuickOpen::benchProjectFileFilter_providerData()
0178 {
0179     QFETCH(int, files);
0180     QFETCH(QString, filter);
0181 
0182     ProjectFileDataProvider provider;
0183     TestProject* project = getProjectWithFiles(files);
0184     projectController->addProject(project);
0185     provider.reset();
0186     QCOMPARE(provider.itemCount(), uint(files));
0187     provider.setFilterText(filter);
0188     QVERIFY(provider.itemCount());
0189     const int itemIdx = provider.itemCount() - 1;
0190     // don't use QBENCHMARK directly as the code below is too fast
0191     // and then QBENCHMARK runs the setup code above multiple times which is overly slow
0192     QBENCHMARK_ONCE
0193     {
0194         for (int i = 0; i < 100000; ++i) {
0195             QuickOpenDataPointer data = provider.data(itemIdx);
0196             data->text();
0197         }
0198     }
0199 }
0200 
0201 void BenchQuickOpen::benchProjectFileFilter_providerData_data()
0202 {
0203     getData();
0204 }
0205 
0206 void BenchQuickOpen::benchProjectFileFilter_providerDataIcon()
0207 {
0208     QFETCH(int, files);
0209     QFETCH(QString, filter);
0210 
0211     ProjectFileDataProvider provider;
0212     TestProject* project = getProjectWithFiles(files);
0213     projectController->addProject(project);
0214     provider.reset();
0215     QCOMPARE(provider.itemCount(), uint(files));
0216     provider.setFilterText(filter);
0217     QVERIFY(provider.itemCount());
0218     const int itemIdx = provider.itemCount() - 1;
0219     // don't use QBENCHMARK directly as the code below is too fast
0220     // and then QBENCHMARK runs the setup code above multiple times which is overly slow
0221     QBENCHMARK_ONCE
0222     {
0223         for (int i = 0; i < 100000; ++i) {
0224             QuickOpenDataPointer data = provider.data(itemIdx);
0225             data->icon();
0226         }
0227     }
0228 }
0229 
0230 void BenchQuickOpen::benchProjectFileFilter_providerDataIcon_data()
0231 {
0232     getData();
0233 }
0234 
0235 void BenchQuickOpen::benchProjectFileFilter_files()
0236 {
0237     QFETCH(QVector<int>, fileCounts);
0238 
0239     ProjectFileDataProvider provider;
0240 
0241     QTemporaryDir dir;
0242     for (int i = 0; i < fileCounts.size(); ++i) {
0243         const Path path{dir.filePath(QStringLiteral("project dir %1").arg(i))};
0244         projectController->addProject(getProjectWithFiles(fileCounts.at(i), path));
0245     }
0246     const auto projects = projectController->projects();
0247 
0248     QFETCH(bool, openSomeDocument);
0249     QUrl openedDocument;
0250     if (openSomeDocument && !projects.empty()) {
0251         openedDocument = openAnyDocument(projects.front());
0252     }
0253 
0254     // don't use QBENCHMARK directly as the code below is too fast
0255     // and then QBENCHMARK runs the setup code above multiple times which is overly slow
0256     QBENCHMARK_ONCE
0257     {
0258         for (int i = 0; i < 100; ++i) {
0259             provider.files();
0260         }
0261     }
0262 
0263     // Verify that the computed result is correct.
0264     QSet<IndexedString> allFiles;
0265     for (const auto* project : projects) {
0266         allFiles += project->fileSet();
0267     }
0268     if (!openedDocument.isEmpty()) {
0269         allFiles -= IndexedString{openedDocument};
0270     }
0271     QCOMPARE(provider.files(), allFiles);
0272 }
0273 
0274 void BenchQuickOpen::benchProjectFileFilter_files_data()
0275 {
0276     using FileCounts = QVector<int>;
0277     QTest::addColumn<FileCounts>("fileCounts");
0278     QTest::addColumn<bool>("openSomeDocument");
0279 
0280     const int files{10000};
0281     QTest::addRow("%d", files) << FileCounts{files} << false;
0282 
0283     for (int files1 : { 1000, 10000 }) {
0284         const int files2{10000};
0285         QTest::addRow("%d, %d", files1, files2) << FileCounts{files1, files2} << false;
0286     }
0287 
0288     const FileCounts fileCounts{100, 5000, 800, 244, 5432, 0, 5, 2222};
0289     QTest::addRow("%d projects", fileCounts.size()) << fileCounts << false;
0290     QTest::addRow("%d projects and one open file", fileCounts.size()) << fileCounts << true;
0291 }
0292 
0293 void BenchQuickOpen::benchProjectFileFilter_fileRemovedFromSet_data()
0294 {
0295     getAddRemoveData();
0296 }
0297 
0298 void BenchQuickOpen::benchProjectFileFilter_fileRemovedFromSet()
0299 {
0300     QFETCH(int, files);
0301 
0302     ProjectFileDataProvider provider;
0303 
0304     auto project = getProjectWithFiles(files);
0305     projectController->addProject(project);
0306 
0307     const auto projectFiles = project->files();
0308     QCOMPARE(projectFiles.size(), files);
0309     QCOMPARE(provider.files().size(), files);
0310 
0311     // don't use QBENCHMARK directly as the code below removes the files after one iteration
0312     QBENCHMARK_ONCE {
0313         qDeleteAll(projectFiles);
0314     }
0315 
0316     QCOMPARE(provider.files().size(), 0);
0317 }
0318 
0319 #include "moc_bench_quickopen.cpp"