cf12defd28
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
289 lines
9.1 KiB
C++
289 lines
9.1 KiB
C++
/*
|
|
SPDX-FileCopyrightText: 2014 Frank Reininghaus <frank78ac@googlemail.com>
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
#include <kio/udsentry.h>
|
|
|
|
#include <QTest>
|
|
|
|
/**
|
|
* This benchmarks tests four typical uses of UDSEntry:
|
|
*
|
|
* (a) Store data in UDSEntries using
|
|
* UDSEntry::insert(uint, const QString&) and
|
|
* UDSEntry::insert(uint, long long),
|
|
* and append the entries to a UDSEntryList.
|
|
*
|
|
* (b) Read data from UDSEntries in a UDSEntryList using
|
|
* UDSEntry::stringValue(uint) and UDSEntry::numberValue(uint).
|
|
*
|
|
* (c) Save a UDSEntryList in a QDataStream.
|
|
*
|
|
* (d) Load a UDSEntryList from a QDataStream.
|
|
*
|
|
* This is done for two different data sets:
|
|
*
|
|
* 1. UDSEntries containing the entries which are provided by kio_file.
|
|
*
|
|
* 2. UDSEntries with a larger number of "fields".
|
|
*/
|
|
|
|
// The following constants control the number of UDSEntries that are considered
|
|
// in each test, and the number of extra "fields" that are used for large UDSEntries.
|
|
const int numberOfSmallUDSEntries = 100 * 1000;
|
|
const int numberOfLargeUDSEntries = 5 * 1000;
|
|
const int extraFieldsForLargeUDSEntries = 40;
|
|
|
|
class UDSEntryBenchmark : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
UDSEntryBenchmark();
|
|
|
|
private Q_SLOTS:
|
|
void createSmallEntries();
|
|
void createLargeEntries();
|
|
void readFieldsFromSmallEntries();
|
|
void readFieldsFromLargeEntries();
|
|
void saveSmallEntries();
|
|
void saveLargeEntries();
|
|
void loadSmallEntries();
|
|
void loadLargeEntries();
|
|
|
|
private:
|
|
KIO::UDSEntryList m_smallEntries;
|
|
KIO::UDSEntryList m_largeEntries;
|
|
QByteArray m_savedSmallEntries;
|
|
QByteArray m_savedLargeEntries;
|
|
|
|
QList<uint> m_fieldsForLargeEntries;
|
|
};
|
|
|
|
UDSEntryBenchmark::UDSEntryBenchmark()
|
|
{
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_SIZE);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_SIZE_LARGE);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_USER);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_ICON_NAME);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_GROUP);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_NAME);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_LOCAL_PATH);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_HIDDEN);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_ACCESS);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_MODIFICATION_TIME);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_ACCESS_TIME);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_CREATION_TIME);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_FILE_TYPE);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_LINK_DEST);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_URL);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_MIME_TYPE);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_GUESSED_MIME_TYPE);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_XML_PROPERTIES);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_EXTENDED_ACL);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_ACL_STRING);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_DEFAULT_ACL_STRING);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_DISPLAY_NAME);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_TARGET_URL);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_DISPLAY_TYPE);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_ICON_OVERLAY_NAMES);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_COMMENT);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_DEVICE_ID);
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_INODE);
|
|
|
|
for (int i = 0; i < extraFieldsForLargeUDSEntries; ++i) {
|
|
m_fieldsForLargeEntries.append(KIO::UDSEntry::UDS_EXTRA + i);
|
|
}
|
|
}
|
|
|
|
void UDSEntryBenchmark::createSmallEntries()
|
|
{
|
|
m_smallEntries.clear();
|
|
m_smallEntries.reserve(numberOfSmallUDSEntries);
|
|
|
|
const QString user = QStringLiteral("user");
|
|
const QString group = QStringLiteral("group");
|
|
|
|
QList<QString> names(numberOfSmallUDSEntries);
|
|
for (int i = 0; i < numberOfSmallUDSEntries; ++i) {
|
|
names[i] = QString::number(i);
|
|
}
|
|
|
|
QBENCHMARK_ONCE {
|
|
for (int i = 0; i < numberOfSmallUDSEntries; ++i) {
|
|
KIO::UDSEntry entry;
|
|
entry.reserve(8);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_NAME, names[i]);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, i);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, i);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_SIZE, i);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_MODIFICATION_TIME, i);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_USER, user);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_GROUP, group);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_ACCESS_TIME, i);
|
|
m_smallEntries.append(entry);
|
|
}
|
|
}
|
|
|
|
Q_ASSERT(m_smallEntries.count() == numberOfSmallUDSEntries);
|
|
}
|
|
|
|
void UDSEntryBenchmark::createLargeEntries()
|
|
{
|
|
m_largeEntries.clear();
|
|
m_largeEntries.reserve(numberOfLargeUDSEntries);
|
|
|
|
QList<QString> names(numberOfLargeUDSEntries);
|
|
for (int i = 0; i < numberOfLargeUDSEntries; ++i) {
|
|
names[i] = QString::number(i);
|
|
}
|
|
|
|
QBENCHMARK_ONCE {
|
|
for (int i = 0; i < numberOfLargeUDSEntries; ++i) {
|
|
KIO::UDSEntry entry;
|
|
entry.reserve(m_fieldsForLargeEntries.count());
|
|
for (uint field : std::as_const(m_fieldsForLargeEntries)) {
|
|
if (field & KIO::UDSEntry::UDS_STRING) {
|
|
entry.fastInsert(field, names[i]);
|
|
} else {
|
|
entry.fastInsert(field, i);
|
|
}
|
|
}
|
|
m_largeEntries.append(entry);
|
|
}
|
|
}
|
|
|
|
Q_ASSERT(m_largeEntries.count() == numberOfLargeUDSEntries);
|
|
}
|
|
|
|
void UDSEntryBenchmark::readFieldsFromSmallEntries()
|
|
{
|
|
// Create the entries if they do not exist yet.
|
|
if (m_smallEntries.isEmpty()) {
|
|
createSmallEntries();
|
|
}
|
|
|
|
const QString user = QStringLiteral("user");
|
|
const QString group = QStringLiteral("group");
|
|
|
|
QBENCHMARK {
|
|
long long i = 0;
|
|
long long entrySum = 0;
|
|
|
|
for (const KIO::UDSEntry &entry : std::as_const(m_smallEntries)) {
|
|
entrySum += entry.count();
|
|
/* clang-format off */
|
|
if (entry.stringValue(KIO::UDSEntry::UDS_NAME).toInt() == i
|
|
&& entry.numberValue(KIO::UDSEntry::UDS_FILE_TYPE) == i
|
|
&& entry.numberValue(KIO::UDSEntry::UDS_ACCESS) == i
|
|
&& entry.numberValue(KIO::UDSEntry::UDS_SIZE) == i
|
|
&& entry.numberValue(KIO::UDSEntry::UDS_MODIFICATION_TIME) == i
|
|
&& entry.stringValue(KIO::UDSEntry::UDS_USER) == user
|
|
&& entry.stringValue(KIO::UDSEntry::UDS_GROUP) == group
|
|
&& entry.numberValue(KIO::UDSEntry::UDS_ACCESS_TIME) == i) { /* clang-format on */
|
|
++i;
|
|
}
|
|
}
|
|
|
|
QCOMPARE(i, numberOfSmallUDSEntries);
|
|
QCOMPARE(entrySum, numberOfSmallUDSEntries * 8);
|
|
}
|
|
}
|
|
|
|
void UDSEntryBenchmark::readFieldsFromLargeEntries()
|
|
{
|
|
// Create the entries if they do not exist yet.
|
|
if (m_largeEntries.isEmpty()) {
|
|
createLargeEntries();
|
|
}
|
|
|
|
QBENCHMARK_ONCE {
|
|
long long i = 0;
|
|
long long fieldSum = 0;
|
|
|
|
for (const KIO::UDSEntry &entry : std::as_const(m_largeEntries)) {
|
|
for (uint field : std::as_const(m_fieldsForLargeEntries)) {
|
|
if (field & KIO::UDSEntry::UDS_STRING) {
|
|
if (entry.stringValue(field).toInt() == i) {
|
|
++fieldSum;
|
|
}
|
|
} else if (entry.numberValue(field) == i) {
|
|
++fieldSum;
|
|
}
|
|
}
|
|
++i;
|
|
}
|
|
|
|
QCOMPARE(fieldSum, m_fieldsForLargeEntries.count() * m_largeEntries.count());
|
|
}
|
|
}
|
|
|
|
void UDSEntryBenchmark::saveSmallEntries()
|
|
{
|
|
// Create the entries if they do not exist yet.
|
|
if (m_smallEntries.isEmpty()) {
|
|
createSmallEntries();
|
|
}
|
|
|
|
m_savedSmallEntries.clear();
|
|
|
|
QBENCHMARK_ONCE {
|
|
QDataStream stream(&m_savedSmallEntries, QIODevice::WriteOnly);
|
|
stream << m_smallEntries;
|
|
}
|
|
}
|
|
|
|
void UDSEntryBenchmark::saveLargeEntries()
|
|
{
|
|
// Create the entries if they do not exist yet.
|
|
if (m_smallEntries.isEmpty()) {
|
|
createLargeEntries();
|
|
}
|
|
|
|
m_savedLargeEntries.clear();
|
|
|
|
QBENCHMARK_ONCE {
|
|
QDataStream stream(&m_savedLargeEntries, QIODevice::WriteOnly);
|
|
stream << m_largeEntries;
|
|
}
|
|
}
|
|
void UDSEntryBenchmark::loadSmallEntries()
|
|
{
|
|
// Save the entries if that has not been done yet.
|
|
if (m_savedSmallEntries.isEmpty()) {
|
|
saveSmallEntries();
|
|
}
|
|
|
|
QDataStream stream(m_savedSmallEntries);
|
|
KIO::UDSEntryList entries;
|
|
|
|
QBENCHMARK_ONCE {
|
|
stream >> entries;
|
|
}
|
|
|
|
QCOMPARE(entries, m_smallEntries);
|
|
}
|
|
|
|
void UDSEntryBenchmark::loadLargeEntries()
|
|
{
|
|
// Save the entries if that has not been done yet.
|
|
if (m_savedLargeEntries.isEmpty()) {
|
|
saveLargeEntries();
|
|
}
|
|
|
|
QDataStream stream(m_savedLargeEntries);
|
|
KIO::UDSEntryList entries;
|
|
|
|
QBENCHMARK_ONCE {
|
|
stream >> entries;
|
|
}
|
|
|
|
QCOMPARE(entries, m_largeEntries);
|
|
}
|
|
|
|
QTEST_MAIN(UDSEntryBenchmark)
|
|
|
|
#include "udsentry_benchmark.moc"
|