File indexing completed on 2024-11-10 09:40:27
0001 /* 0002 SPDX-FileCopyrightText: 2014 Frank Reininghaus <frank78ac@googlemail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <kio/udsentry.h> 0008 0009 #include <QTest> 0010 0011 /** 0012 * This benchmarks tests four typical uses of UDSEntry: 0013 * 0014 * (a) Store data in UDSEntries using 0015 * UDSEntry::insert(uint, const QString&) and 0016 * UDSEntry::insert(uint, long long), 0017 * and append the entries to a UDSEntryList. 0018 * 0019 * (b) Read data from UDSEntries in a UDSEntryList using 0020 * UDSEntry::stringValue(uint) and UDSEntry::numberValue(uint). 0021 * 0022 * (c) Save a UDSEntryList in a QDataStream. 0023 * 0024 * (d) Load a UDSEntryList from a QDataStream. 0025 * 0026 * This is done for two different data sets: 0027 * 0028 * 1. UDSEntries containing the entries which are provided by kio_file. 0029 * 0030 * 2. UDSEntries with a larger number of "fields". 0031 */ 0032 0033 // The following constants control the number of UDSEntries that are considered 0034 // in each test, and the number of extra "fields" that are used for large UDSEntries. 0035 const int numberOfSmallUDSEntries = 100 * 1000; 0036 const int numberOfLargeUDSEntries = 5 * 1000; 0037 const int extraFieldsForLargeUDSEntries = 40; 0038 0039 class UDSEntryBenchmark : public QObject 0040 { 0041 Q_OBJECT 0042 0043 public: 0044 UDSEntryBenchmark(); 0045 0046 private Q_SLOTS: 0047 void createSmallEntries(); 0048 void createLargeEntries(); 0049 void readFieldsFromSmallEntries(); 0050 void readFieldsFromLargeEntries(); 0051 void saveSmallEntries(); 0052 void saveLargeEntries(); 0053 void loadSmallEntries(); 0054 void loadLargeEntries(); 0055 0056 private: 0057 KIO::UDSEntryList m_smallEntries; 0058 KIO::UDSEntryList m_largeEntries; 0059 QByteArray m_savedSmallEntries; 0060 QByteArray m_savedLargeEntries; 0061 0062 QVector<uint> m_fieldsForLargeEntries; 0063 }; 0064 0065 UDSEntryBenchmark::UDSEntryBenchmark() 0066 { 0067 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_SIZE); 0068 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_SIZE_LARGE); 0069 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_USER); 0070 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_ICON_NAME); 0071 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_GROUP); 0072 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_NAME); 0073 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_LOCAL_PATH); 0074 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_HIDDEN); 0075 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_ACCESS); 0076 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_MODIFICATION_TIME); 0077 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_ACCESS_TIME); 0078 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_CREATION_TIME); 0079 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_FILE_TYPE); 0080 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_LINK_DEST); 0081 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_URL); 0082 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_MIME_TYPE); 0083 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_GUESSED_MIME_TYPE); 0084 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_XML_PROPERTIES); 0085 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_EXTENDED_ACL); 0086 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_ACL_STRING); 0087 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_DEFAULT_ACL_STRING); 0088 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_DISPLAY_NAME); 0089 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_TARGET_URL); 0090 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_DISPLAY_TYPE); 0091 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_ICON_OVERLAY_NAMES); 0092 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_COMMENT); 0093 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_DEVICE_ID); 0094 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_INODE); 0095 0096 for (int i = 0; i < extraFieldsForLargeUDSEntries; ++i) { 0097 m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_EXTRA + i); 0098 } 0099 } 0100 0101 void UDSEntryBenchmark::createSmallEntries() 0102 { 0103 m_smallEntries.clear(); 0104 m_smallEntries.reserve(numberOfSmallUDSEntries); 0105 0106 const QString user = QStringLiteral("user"); 0107 const QString group = QStringLiteral("group"); 0108 0109 QVector<QString> names(numberOfSmallUDSEntries); 0110 for (int i = 0; i < numberOfSmallUDSEntries; ++i) { 0111 names[i] = QString::number(i); 0112 } 0113 0114 QBENCHMARK_ONCE { 0115 for (int i = 0; i < numberOfSmallUDSEntries; ++i) { 0116 KIO::UDSEntry entry; 0117 entry.reserve(8); 0118 entry.fastInsert(KIO::UDSEntry::UDS_NAME, names[i]); 0119 entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, i); 0120 entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, i); 0121 entry.fastInsert(KIO::UDSEntry::UDS_SIZE, i); 0122 entry.fastInsert(KIO::UDSEntry::UDS_MODIFICATION_TIME, i); 0123 entry.fastInsert(KIO::UDSEntry::UDS_USER, user); 0124 entry.fastInsert(KIO::UDSEntry::UDS_GROUP, group); 0125 entry.fastInsert(KIO::UDSEntry::UDS_ACCESS_TIME, i); 0126 m_smallEntries.append(entry); 0127 } 0128 } 0129 0130 Q_ASSERT(m_smallEntries.count() == numberOfSmallUDSEntries); 0131 } 0132 0133 void UDSEntryBenchmark::createLargeEntries() 0134 { 0135 m_largeEntries.clear(); 0136 m_largeEntries.reserve(numberOfLargeUDSEntries); 0137 0138 QVector<QString> names(numberOfLargeUDSEntries); 0139 for (int i = 0; i < numberOfLargeUDSEntries; ++i) { 0140 names[i] = QString::number(i); 0141 } 0142 0143 QBENCHMARK_ONCE { 0144 for (int i = 0; i < numberOfLargeUDSEntries; ++i) { 0145 KIO::UDSEntry entry; 0146 entry.reserve(m_fieldsForLargeEntries.count()); 0147 for (uint field : std::as_const(m_fieldsForLargeEntries)) { 0148 if (field & KIO::UDSEntry::UDS_STRING) { 0149 entry.fastInsert(field, names[i]); 0150 } else { 0151 entry.fastInsert(field, i); 0152 } 0153 } 0154 m_largeEntries.append(entry); 0155 } 0156 } 0157 0158 Q_ASSERT(m_largeEntries.count() == numberOfLargeUDSEntries); 0159 } 0160 0161 void UDSEntryBenchmark::readFieldsFromSmallEntries() 0162 { 0163 // Create the entries if they do not exist yet. 0164 if (m_smallEntries.isEmpty()) { 0165 createSmallEntries(); 0166 } 0167 0168 const QString user = QStringLiteral("user"); 0169 const QString group = QStringLiteral("group"); 0170 0171 QBENCHMARK { 0172 long long i = 0; 0173 long long entrySum = 0; 0174 0175 for (const KIO::UDSEntry &entry : std::as_const(m_smallEntries)) { 0176 entrySum += entry.count(); 0177 /* clang-format off */ 0178 if (entry.stringValue(KIO::UDSEntry::UDS_NAME).toInt() == i 0179 && entry.numberValue(KIO::UDSEntry::UDS_FILE_TYPE) == i 0180 && entry.numberValue(KIO::UDSEntry::UDS_ACCESS) == i 0181 && entry.numberValue(KIO::UDSEntry::UDS_SIZE) == i 0182 && entry.numberValue(KIO::UDSEntry::UDS_MODIFICATION_TIME) == i 0183 && entry.stringValue(KIO::UDSEntry::UDS_USER) == user 0184 && entry.stringValue(KIO::UDSEntry::UDS_GROUP) == group 0185 && entry.numberValue(KIO::UDSEntry::UDS_ACCESS_TIME) == i) { /* clang-format on */ 0186 ++i; 0187 } 0188 } 0189 0190 QCOMPARE(i, numberOfSmallUDSEntries); 0191 QCOMPARE(entrySum, numberOfSmallUDSEntries * 8); 0192 } 0193 } 0194 0195 void UDSEntryBenchmark::readFieldsFromLargeEntries() 0196 { 0197 // Create the entries if they do not exist yet. 0198 if (m_largeEntries.isEmpty()) { 0199 createLargeEntries(); 0200 } 0201 0202 QBENCHMARK_ONCE { 0203 long long i = 0; 0204 long long fieldSum = 0; 0205 0206 for (const KIO::UDSEntry &entry : std::as_const(m_largeEntries)) { 0207 for (uint field : std::as_const(m_fieldsForLargeEntries)) { 0208 if (field & KIO::UDSEntry::UDS_STRING) { 0209 if (entry.stringValue(field).toInt() == i) { 0210 ++fieldSum; 0211 } 0212 } else if (entry.numberValue(field) == i) { 0213 ++fieldSum; 0214 } 0215 } 0216 ++i; 0217 } 0218 0219 QCOMPARE(fieldSum, m_fieldsForLargeEntries.count() * m_largeEntries.count()); 0220 } 0221 } 0222 0223 void UDSEntryBenchmark::saveSmallEntries() 0224 { 0225 // Create the entries if they do not exist yet. 0226 if (m_smallEntries.isEmpty()) { 0227 createSmallEntries(); 0228 } 0229 0230 m_savedSmallEntries.clear(); 0231 0232 QBENCHMARK_ONCE { 0233 QDataStream stream(&m_savedSmallEntries, QIODevice::WriteOnly); 0234 stream << m_smallEntries; 0235 } 0236 } 0237 0238 void UDSEntryBenchmark::saveLargeEntries() 0239 { 0240 // Create the entries if they do not exist yet. 0241 if (m_smallEntries.isEmpty()) { 0242 createLargeEntries(); 0243 } 0244 0245 m_savedLargeEntries.clear(); 0246 0247 QBENCHMARK_ONCE { 0248 QDataStream stream(&m_savedLargeEntries, QIODevice::WriteOnly); 0249 stream << m_largeEntries; 0250 } 0251 } 0252 void UDSEntryBenchmark::loadSmallEntries() 0253 { 0254 // Save the entries if that has not been done yet. 0255 if (m_savedSmallEntries.isEmpty()) { 0256 saveSmallEntries(); 0257 } 0258 0259 QDataStream stream(m_savedSmallEntries); 0260 KIO::UDSEntryList entries; 0261 0262 QBENCHMARK_ONCE { 0263 stream >> entries; 0264 } 0265 0266 QCOMPARE(entries, m_smallEntries); 0267 } 0268 0269 void UDSEntryBenchmark::loadLargeEntries() 0270 { 0271 // Save the entries if that has not been done yet. 0272 if (m_savedLargeEntries.isEmpty()) { 0273 saveLargeEntries(); 0274 } 0275 0276 QDataStream stream(m_savedLargeEntries); 0277 KIO::UDSEntryList entries; 0278 0279 QBENCHMARK_ONCE { 0280 stream >> entries; 0281 } 0282 0283 QCOMPARE(entries, m_largeEntries); 0284 } 0285 0286 QTEST_MAIN(UDSEntryBenchmark) 0287 0288 #include "udsentry_benchmark.moc"