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"