diff options
Diffstat (limited to 'tests/benchmarks/corelib')
49 files changed, 5521 insertions, 0 deletions
diff --git a/tests/benchmarks/corelib/corelib.pro b/tests/benchmarks/corelib/corelib.pro new file mode 100644 index 0000000..72fca33 --- /dev/null +++ b/tests/benchmarks/corelib/corelib.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs +SUBDIRS = \ + io \ + kernel \ + thread \ + tools diff --git a/tests/benchmarks/corelib/io/io.pro b/tests/benchmarks/corelib/io/io.pro new file mode 100644 index 0000000..97445d7 --- /dev/null +++ b/tests/benchmarks/corelib/io/io.pro @@ -0,0 +1,9 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qdir \ + qdiriterator \ + qfile \ + qfileinfo \ + qiodevice \ + qtemporaryfile + diff --git a/tests/benchmarks/corelib/io/qdir/qdir.pro b/tests/benchmarks/corelib/io/qdir/qdir.pro new file mode 100644 index 0000000..2cdebfd --- /dev/null +++ b/tests/benchmarks/corelib/io/qdir/qdir.pro @@ -0,0 +1,8 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qdir +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += tst_qdir.cpp diff --git a/tests/benchmarks/corelib/io/qdir/tst_qdir.cpp b/tests/benchmarks/corelib/io/qdir/tst_qdir.cpp new file mode 100644 index 0000000..aea9fd0 --- /dev/null +++ b/tests/benchmarks/corelib/io/qdir/tst_qdir.cpp @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#ifdef Q_OS_WIN +# include <windows.h> +#else +# include <sys/stat.h> +# include <sys/types.h> +# include <dirent.h> +# include <unistd.h> +#endif + +class Test : public QObject{ + Q_OBJECT +public slots: + void initTestCase() { + QDir testdir = QDir::tempPath(); + + const QString subfolder_name = QLatin1String("test_speed"); + QVERIFY(testdir.mkdir(subfolder_name)); + QVERIFY(testdir.cd(subfolder_name)); + + for (uint i=0; i<10000; ++i) { + QFile file(testdir.absolutePath() + "/testfile_" + QString::number(i)); + file.open(QIODevice::WriteOnly); + } + } + void cleanupTestCase() { + { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + testdir.setSorting(QDir::Unsorted); + testdir.setFilter(QDir::AllEntries | QDir::System | QDir::Hidden); + foreach (const QString &filename, testdir.entryList()) { + testdir.remove(filename); + } + } + const QDir temp = QDir(QDir::tempPath()); + temp.rmdir(QLatin1String("test_speed")); + } +private slots: + void baseline() {} + + void sizeSpeed() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + QBENCHMARK { + QFileInfoList fileInfoList = testdir.entryInfoList(QDir::Files, QDir::Unsorted); + foreach (const QFileInfo &fileInfo, fileInfoList) { + fileInfo.isDir(); + fileInfo.size(); + } + } + } + void sizeSpeedIterator() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + QBENCHMARK { + QDirIterator dit(testdir.path(), QDir::Files); + while (dit.hasNext()) { + dit.fileInfo().isDir(); + dit.fileInfo().size(); + dit.next(); + } + } + } + + void sizeSpeedWithoutFilter() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + QBENCHMARK { + QFileInfoList fileInfoList = testdir.entryInfoList(QDir::NoFilter, QDir::Unsorted); + foreach (const QFileInfo &fileInfo, fileInfoList) { + fileInfo.size(); + } + } + } + void sizeSpeedWithoutFilterIterator() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + QBENCHMARK { + QDirIterator dit(testdir.path()); + while (dit.hasNext()) { + dit.fileInfo().isDir(); + dit.fileInfo().size(); + dit.next(); + } + } + } + + void sizeSpeedWithoutFileInfoList() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + testdir.setSorting(QDir::Unsorted); + QBENCHMARK { + QStringList fileList = testdir.entryList(QDir::NoFilter, QDir::Unsorted); + foreach (const QString &filename, fileList) { + QFileInfo fileInfo(filename); + fileInfo.size(); + } + } + } + + void iDontWantAnyStat() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + testdir.setSorting(QDir::Unsorted); + testdir.setFilter(QDir::AllEntries | QDir::System | QDir::Hidden); + QBENCHMARK { + QStringList fileList = testdir.entryList(QDir::NoFilter, QDir::Unsorted); + foreach (const QString &filename, fileList) { + + } + } + } + void iDontWantAnyStatIterator() { + QBENCHMARK { + QDirIterator dit(QDir::tempPath() + QLatin1String("/test_speed")); + while (dit.hasNext()) { + dit.next(); + } + } + } + + void sizeSpeedWithoutFilterLowLevel() { +#ifdef Q_OS_WIN + const wchar_t *dirpath = (wchar_t*)testdir.absolutePath().utf16(); + wchar_t appendedPath[MAX_PATH]; + wcscpy(appendedPath, dirpath); + wcscat(appendedPath, L"\\*"); + + WIN32_FIND_DATA fd; + HANDLE hSearch = FindFirstFileW(appendedPath, &fd); + QVERIFY(hSearch == INVALID_HANDLE_VALUE); + + QBENCHMARK { + do { + + } while (FindNextFile(hSearch, &fd)); + } + FindClose(hSearch); +#else + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + DIR *dir = opendir(qPrintable(testdir.absolutePath())); + QVERIFY(dir); + + QVERIFY(!chdir(qPrintable(testdir.absolutePath()))); + QBENCHMARK { + struct dirent *item = readdir(dir); + while (item) { + char *fileName = item->d_name; + + struct stat fileStat; + QVERIFY(!stat(fileName, &fileStat)); + + item = readdir(dir); + } + } + closedir(dir); +#endif + } +}; + +QTEST_MAIN(Test) +#include "tst_qdir.moc" diff --git a/tests/benchmarks/corelib/io/qdiriterator/main.cpp b/tests/benchmarks/corelib/io/qdiriterator/main.cpp new file mode 100644 index 0000000..afa6b7b --- /dev/null +++ b/tests/benchmarks/corelib/io/qdiriterator/main.cpp @@ -0,0 +1,251 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QDebug> +#include <QDirIterator> +#include <QString> + +#ifdef Q_OS_WIN +# include <windows.h> +# include <atlbase.h> +#else +# include <sys/stat.h> +# include <sys/types.h> +# include <dirent.h> +# include <errno.h> +# include <string.h> +#endif + +#include <qtest.h> + +#include "qfilesystemiterator.h" + +class tst_qdiriterator : public QObject +{ + Q_OBJECT +private slots: + void posix(); + void posix_data() { data(); } + void diriterator(); + void diriterator_data() { data(); } + void fsiterator(); + void fsiterator_data() { data(); } + void data(); +}; + + +void tst_qdiriterator::data() +{ +#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) + QByteArray qtdir = qPrintable(QCoreApplication::applicationDirPath()); + qtdir += "/depot"; +#else +#if defined(Q_OS_WIN) + const char *qtdir = "C:\\depot\\qt\\main"; +#else + const char *qtdir = ::getenv("QTDIR"); +#endif + if (!qtdir) { + fprintf(stderr, "QTDIR not set\n"); + exit(1); + } +#endif + + QTest::addColumn<QByteArray>("dirpath"); + QByteArray ba = QByteArray(qtdir) + "/src/corelib"; + QByteArray ba1 = ba + "/io"; + QTest::newRow(ba) << ba; + //QTest::newRow(ba1) << ba1; +} + +#ifdef Q_OS_WIN +static int posix_helper(const wchar_t *dirpath) +{ + int count = 0; + HANDLE hSearch; + WIN32_FIND_DATA fd; + + const size_t origDirPathLength = wcslen(dirpath); + + wchar_t appendedPath[MAX_PATH]; + wcscpy(appendedPath, dirpath); + wcscat(appendedPath, L"\\*"); + hSearch = FindFirstFile(appendedPath, &fd); + appendedPath[origDirPathLength] = 0; + + if (hSearch == INVALID_HANDLE_VALUE) { + qWarning("FindFirstFile failed"); + return count; + } + + do { + if (!(fd.cFileName[0] == L'.' && fd.cFileName[1] == 0) && + !(fd.cFileName[0] == L'.' && fd.cFileName[1] == L'.' && fd.cFileName[2] == 0)) + { + if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + wcscat(appendedPath, L"\\"); + wcscat(appendedPath, fd.cFileName); + count += posix_helper(appendedPath); + appendedPath[origDirPathLength] = 0; + } + else { + ++count; + } + } + } while (FindNextFile(hSearch, &fd)); + FindClose(hSearch); + + return count; +} + +#else + +static int posix_helper(const char *dirpath) +{ + //qDebug() << "DIR" << dirpath; + DIR *dir = ::opendir(dirpath); + if (!dir) + return 0; + + dirent *entry = 0; + + int count = 0; + while ((entry = ::readdir(dir))) { + if (qstrcmp(entry->d_name, ".") == 0) + continue; + if (qstrcmp(entry->d_name, "..") == 0) + continue; + ++count; + QByteArray ba = dirpath; + ba += '/'; + ba += entry->d_name; + struct stat st; + lstat(ba.constData(), &st); + if (S_ISDIR(st.st_mode)) + count += posix_helper(ba.constData()); + } + + ::closedir(dir); + return count; +} +#endif + + +void tst_qdiriterator::posix() +{ + QFETCH(QByteArray, dirpath); + + int count = 0; + QString path(dirpath); + QBENCHMARK { +#ifdef Q_OS_WIN + count = posix_helper(path.utf16()); +#else + count = posix_helper(dirpath.constData()); +#endif + } + qDebug() << count; +} + +void tst_qdiriterator::diriterator() +{ + QFETCH(QByteArray, dirpath); + + int count = 0; + + QBENCHMARK { + int c = 0; + + QDirIterator dir(dirpath, + //QDir::AllEntries | QDir::Hidden | QDir::NoDotAndDotDot, + //QDir::AllEntries | QDir::Hidden, + QDir::Files, + QDirIterator::Subdirectories); + + while (dir.hasNext()) { + dir.next(); + //printf("%s\n", qPrintable(dir.fileName())); + 0 && printf("%d %s\n", + dir.fileInfo().isDir(), + //qPrintable(dir.fileInfo().absoluteFilePath()), + //qPrintable(dir.path()), + qPrintable(dir.filePath())); + ++c; + } + count = c; + } + qDebug() << count; +} + +void tst_qdiriterator::fsiterator() +{ + QFETCH(QByteArray, dirpath); + + int count = 0; + int dump = 0; + + QBENCHMARK { + int c = 0; + + dump && printf("\n\n\n\n"); + QFileSystemIterator dir(dirpath, + //QDir::AllEntries | QDir::Hidden | QDir::NoDotAndDotDot, + //QDir::AllEntries | QDir::Hidden, + //QDir::Files | QDir::NoDotAndDotDot, + QDir::Files, + QFileSystemIterator::Subdirectories); + + for (; !dir.atEnd(); dir.next()) { + dump && printf("%d %s\n", + dir.fileInfo().isDir(), + //qPrintable(dir.fileInfo().absoluteFilePath()), + //qPrintable(dir.path()), + qPrintable(dir.filePath()) + ); + ++c; + } + count = c; + } + qDebug() << count; +} + +QTEST_MAIN(tst_qdiriterator) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/io/qdiriterator/qdiriterator.pro b/tests/benchmarks/corelib/io/qdiriterator/qdiriterator.pro new file mode 100755 index 0000000..e06d746 --- /dev/null +++ b/tests/benchmarks/corelib/io/qdiriterator/qdiriterator.pro @@ -0,0 +1,23 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qdiriterator +DEPENDPATH += . +INCLUDEPATH += . + +QT -= gui + +CONFIG += release +CONFIG += debug + + +SOURCES += main.cpp + +SOURCES += qfilesystemiterator.cpp +HEADERS += qfilesystemiterator.h + +wince*|symbian: { + corelibdir.sources = $$QT_SOURCE_TREE/src/corelib + corelibdir.path = ./depot/src + DEPLOYMENT += corelibdir +} + diff --git a/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp new file mode 100644 index 0000000..267d53f --- /dev/null +++ b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp @@ -0,0 +1,678 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \since 4.5 + \class QFileSystemIterator + \brief The QFileSystemIterator class provides an iterator for directory entrylists. + + You can use QFileSystemIterator to navigate entries of a directory one at a time. + It is similar to QDir::entryList() and QDir::entryInfoList(), but because + it lists entries one at a time instead of all at once, it scales better + and is more suitable for large directories. It also supports listing + directory contents recursively, and following symbolic links. Unlike + QDir::entryList(), QFileSystemIterator does not support sorting. + + The QFileSystemIterator constructor takes a QDir or a directory as + argument. After construction, the iterator is located before the first + directory entry. Here's how to iterate over all the entries sequentially: + + \snippet doc/src/snippets/code/src.corelib.io.qdiriterator.cpp 0 + + The next() function returns the path to the next directory entry and + advances the iterator. You can also call filePath() to get the current + file path without advancing the iterator. The fileName() function returns + only the name of the file, similar to how QDir::entryList() works. You can + also call fileInfo() to get a QFileInfo for the current entry. + + Unlike Qt's container iterators, QFileSystemIterator is uni-directional (i.e., + you cannot iterate directories in reverse order) and does not allow random + access. + + QFileSystemIterator works with all supported file engines, and is implemented + using QAbstractFileEngineIterator. + + \sa QDir, QDir::entryList(), QAbstractFileEngineIterator +*/ + +/*! \enum QFileSystemIterator::IteratorFlag + + This enum describes flags that you can combine to configure the behavior + of QFileSystemIterator. + + \value NoIteratorFlags The default value, representing no flags. The + iterator will return entries for the assigned path. + + \value Subdirectories List entries inside all subdirectories as well. + + \value FollowSymlinks When combined with Subdirectories, this flag + enables iterating through all subdirectories of the assigned path, + following all symbolic links. Symbolic link loops (e.g., "link" => "." or + "link" => "..") are automatically detected and ignored. +*/ + +#include "qfilesystemiterator.h" + +#include <QDebug> +#include <QtCore/qset.h> +#include <QtCore/qstack.h> +#include <QtCore/qvariant.h> + +#ifdef Q_OS_WIN +# include <windows.h> +# include <atlbase.h> +#else +# include <sys/stat.h> +# include <sys/types.h> +# include <dirent.h> +# include <errno.h> +#endif + +QT_BEGIN_NAMESPACE + +class QFileSystemIteratorPrivate +{ +public: + QFileSystemIteratorPrivate(const QString &path, const QStringList &nameFilters, + QDir::Filters filters, QFileSystemIterator::IteratorFlags flags); + ~QFileSystemIteratorPrivate(); + + void pushSubDirectory(const QByteArray &path); + void advance(); + bool isAcceptable() const; + bool shouldFollowDirectory(const QFileInfo &); + //bool matchesFilters(const QAbstractFileEngineIterator *it) const; + inline bool atEnd() const { return m_dirPaths.isEmpty(); } + +#ifdef Q_OS_WIN + QStack<HANDLE> m_dirStructs; + WIN32_FIND_DATA* m_entry; + WIN32_FIND_DATA m_fileSearchResult; + bool m_bFirstSearchResult; +#else + QStack<DIR *> m_dirStructs; + dirent *m_entry; +#endif + + QSet<QString> visitedLinks; + QStack<QByteArray> m_dirPaths; + QFileInfo fileInfo; + QString currentFilePath; + QFileSystemIterator::IteratorFlags iteratorFlags; + QDir::Filters filters; + QStringList nameFilters; + + enum { DontShowDir, ShowDotDotDir, ShowDotDir, ShowDir } + m_currentDirShown, m_nextDirShown; + + QFileSystemIterator *q; + +private: + bool advanceHelper(); // returns true if we know we have something suitable +}; + +/*! + \internal +*/ +QFileSystemIteratorPrivate::QFileSystemIteratorPrivate(const QString &path, + const QStringList &nameFilters, QDir::Filters filters, + QFileSystemIterator::IteratorFlags flags) + : iteratorFlags(flags) +{ + if (filters == QDir::NoFilter) + filters = QDir::AllEntries; + this->filters = filters; + this->nameFilters = nameFilters; + + fileInfo.setFile(path); + QString dir = fileInfo.isSymLink() ? fileInfo.canonicalFilePath() : path; + pushSubDirectory(dir.toLocal8Bit()); + // skip to acceptable entry + while (true) { + if (atEnd()) + return; + if (isAcceptable()) + return; + if (advanceHelper()) + return; + } +} + +/*! + \internal +*/ +QFileSystemIteratorPrivate::~QFileSystemIteratorPrivate() +{ +#ifdef Q_OS_WIN + while (!m_dirStructs.isEmpty()) + ::FindClose(m_dirStructs.pop()); +#else + while (!m_dirStructs.isEmpty()) + ::closedir(m_dirStructs.pop()); +#endif +} + +#ifdef Q_OS_WIN +static bool isDotOrDotDot(const wchar_t* name) +{ + if (name[0] == L'.' && name[1] == 0) + return true; + if (name[0] == L'.' && name[1] == L'.' && name[2] == 0) + return true; + return false; +} +#else +static bool isDotOrDotDot(const char *name) +{ + if (name[0] == '.' && name[1] == 0) + return true; + if (name[0] == '.' && name[1] == '.' && name[2] == 0) + return true; + return false; +} +#endif + +/*! + \internal +*/ +void QFileSystemIteratorPrivate::pushSubDirectory(const QByteArray &path) +{ +/* + if (iteratorFlags & QFileSystemIterator::FollowSymlinks) { + if (fileInfo.filePath() != path) + fileInfo.setFile(path); + if (fileInfo.isSymLink()) { + visitedLinks << fileInfo.canonicalFilePath(); + } else { + visitedLinks << fileInfo.absoluteFilePath(); + } + } +*/ + +#ifdef Q_OS_WIN + wchar_t szSearchPath[MAX_PATH]; + wcscpy(szSearchPath, QString(path).utf16()); + wcscat(szSearchPath, L"\\*"); + HANDLE dir = FindFirstFile(szSearchPath, &m_fileSearchResult); + m_bFirstSearchResult = true; +#else + DIR *dir = ::opendir(path.constData()); + //m_entry = ::readdir(dir); + //while (m_entry && isDotOrDotDot(m_entry->d_name)) + // m_entry = ::readdir(m_dirStructs.top()); +#endif + m_dirStructs.append(dir); + m_dirPaths.append(path); + m_entry = 0; + if (filters & QDir::Dirs) + m_nextDirShown = ShowDir; + else + m_nextDirShown = DontShowDir; + m_currentDirShown = DontShowDir; +} + +/*! + \internal +*/ +bool QFileSystemIteratorPrivate::isAcceptable() const +{ + if (!m_entry) + return false; + return true; +} + +/*! + \internal +*/ + + +void QFileSystemIteratorPrivate::advance() +{ + while (true) { + if (advanceHelper()) + return; + if (atEnd()) + return; + if (isAcceptable()) + return; + } +} + +bool QFileSystemIteratorPrivate::advanceHelper() +{ + if (m_dirStructs.isEmpty()) + return true; + + //printf("ADV %d %d\n", int(m_currentDirShown), int(m_nextDirShown)); + + if ((filters & QDir::Dirs)) { + m_currentDirShown = m_nextDirShown; + if (m_nextDirShown == ShowDir) { + //printf("RESTING ON DIR %s %x\n", m_dirPaths.top().constData(), int(filters)); + m_nextDirShown = (filters & QDir::NoDotAndDotDot) ? DontShowDir : ShowDotDir; + // skip start directory itself + if (m_dirStructs.size() == 1 && m_currentDirShown == ShowDir) + return advanceHelper(); + return true; + } + if (m_nextDirShown == ShowDotDir) { + //printf("RESTING ON DOT %s %x\n", m_dirPaths.top().constData(), int(filters)); + m_nextDirShown = ShowDotDotDir; + return true; + } + if (m_nextDirShown == ShowDotDotDir) { + //printf("RESTING ON DOTDOT %s %x\n", m_dirPaths.top().constData(), int(filters)); + m_nextDirShown = DontShowDir; + return true; + } + m_currentDirShown = DontShowDir; + } + +#ifdef Q_OS_WIN + m_entry = &m_fileSearchResult; + if (m_bFirstSearchResult) { + m_bFirstSearchResult = false; + } else { + if (!FindNextFile(m_dirStructs.top(), m_entry)) + m_entry = 0; + } + + while (m_entry && isDotOrDotDot(m_entry->cFileName)) + if (!FindNextFile(m_dirStructs.top(), m_entry)) + m_entry = 0; + + if (!m_entry) { + m_dirPaths.pop(); + FindClose(m_dirStructs.pop()); + return false; + } + + if (m_entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + QByteArray ba = m_dirPaths.top(); + ba += '\\'; + ba += QString::fromWCharArray(m_entry->cFileName); + pushSubDirectory(ba); + } +#else + m_entry = ::readdir(m_dirStructs.top()); + while (m_entry && isDotOrDotDot(m_entry->d_name)) + m_entry = ::readdir(m_dirStructs.top()); + //return false; // further iteration possibly needed + //printf("READ %p %s\n", m_entry, m_entry ? m_entry->d_name : ""); + + if (!m_entry) { + m_dirPaths.pop(); + DIR *dir = m_dirStructs.pop(); + ::closedir(dir); + return false; // further iteration possibly needed + } + + const char *name = m_entry->d_name; + + QByteArray ba = m_dirPaths.top(); + ba += '/'; + ba += name; + struct stat st; + lstat(ba.constData(), &st); + + if (S_ISDIR(st.st_mode)) { + pushSubDirectory(ba); + return false; // further iteration possibly needed + } +#endif + return false; // further iteration possiblye needed +} + +/*! + \internal + */ +bool QFileSystemIteratorPrivate::shouldFollowDirectory(const QFileInfo &fileInfo) +{ + // If we're doing flat iteration, we're done. + if (!(iteratorFlags & QFileSystemIterator::Subdirectories)) + return false; + + // Never follow non-directory entries + if (!fileInfo.isDir()) + return false; + + + // Never follow . and .. + if (fileInfo.fileName() == QLatin1String(".") || fileInfo.fileName() == QLatin1String("..")) + return false; + + + // Check symlinks + if (fileInfo.isSymLink() && !(iteratorFlags & QFileSystemIterator::FollowSymlinks)) { + // Follow symlinks only if FollowSymlinks was passed + return false; + } + + // Stop link loops + if (visitedLinks.contains(fileInfo.canonicalFilePath())) + return false; + + return true; +} + + +/*! + \internal + + This convenience function implements the iterator's filtering logics and + applies then to the current directory entry. + + It returns true if the current entry matches the filters (i.e., the + current entry will be returned as part of the directory iteration); + otherwise, false is returned. +*/ +#if 0 +bool QFileSystemIteratorPrivate::matchesFilters(const QAbstractFileEngineIterator *it) const +{ + const bool filterPermissions = ((filters & QDir::PermissionMask) + && (filters & QDir::PermissionMask) != QDir::PermissionMask); + const bool skipDirs = !(filters & (QDir::Dirs | QDir::AllDirs)); + const bool skipFiles = !(filters & QDir::Files); + const bool skipSymlinks = (filters & QDir::NoSymLinks); + const bool doReadable = !filterPermissions || (filters & QDir::Readable); + const bool doWritable = !filterPermissions || (filters & QDir::Writable); + const bool doExecutable = !filterPermissions || (filters & QDir::Executable); + const bool includeHidden = (filters & QDir::Hidden); + const bool includeSystem = (filters & QDir::System); + +#ifndef QT_NO_REGEXP + // Prepare name filters + QList<QRegExp> regexps; + bool hasNameFilters = !nameFilters.isEmpty() && !(nameFilters.contains(QLatin1String("*"))); + if (hasNameFilters) { + for (int i = 0; i < nameFilters.size(); ++i) { + regexps << QRegExp(nameFilters.at(i), + (filters & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive, + QRegExp::Wildcard); + } + } +#endif + + QString fileName = it->currentFileName(); + if (fileName.isEmpty()) { + // invalid entry + return false; + } + + QFileInfo fi = it->currentFileInfo(); + QString filePath = it->currentFilePath(); + +#ifndef QT_NO_REGEXP + // Pass all entries through name filters, except dirs if the AllDirs + // filter is passed. + if (hasNameFilters && !((filters & QDir::AllDirs) && fi.isDir())) { + bool matched = false; + for (int i = 0; i < regexps.size(); ++i) { + if (regexps.at(i).exactMatch(fileName)) { + matched = true; + break; + } + } + if (!matched) + return false; + } +#endif + + bool dotOrDotDot = (fileName == QLatin1String(".") || fileName == QLatin1String("..")); + if ((filters & QDir::NoDotAndDotDot) && dotOrDotDot) + return false; + + bool isHidden = !dotOrDotDot && fi.isHidden(); + if (!includeHidden && isHidden) + return false; + + bool isSystem = (!fi.isFile() && !fi.isDir() && !fi.isSymLink()) + || (!fi.exists() && fi.isSymLink()); + if (!includeSystem && isSystem) + return false; + + bool alwaysShow = (filters & QDir::TypeMask) == 0 + && ((isHidden && includeHidden) + || (includeSystem && isSystem)); + + // Skip files and directories + if ((filters & QDir::AllDirs) == 0 && skipDirs && fi.isDir()) { + if (!alwaysShow) + return false; + } + + if ((skipFiles && (fi.isFile() || !fi.exists())) + || (skipSymlinks && fi.isSymLink())) { + if (!alwaysShow) + return false; + } + + if (filterPermissions + && ((doReadable && !fi.isReadable()) + || (doWritable && !fi.isWritable()) + || (doExecutable && !fi.isExecutable()))) { + return false; + } + + if (!includeSystem && !dotOrDotDot && ((fi.exists() && !fi.isFile() && !fi.isDir() && !fi.isSymLink()) + || (!fi.exists() && fi.isSymLink()))) { + return false; + } + + return true; +} +#endif + +/*! + Constructs a QFileSystemIterator that can iterate over \a dir's entrylist, using + \a dir's name filters and regular filters. You can pass options via \a + flags to decide how the directory should be iterated. + + By default, \a flags is NoIteratorFlags, which provides the same behavior + as in QDir::entryList(). + + The sorting in \a dir is ignored. + + \sa atEnd(), next(), IteratorFlags +*/ +QFileSystemIterator::QFileSystemIterator(const QDir &dir, IteratorFlags flags) + : d(new QFileSystemIteratorPrivate(dir.path(), dir.nameFilters(), dir.filter(), flags)) +{ + d->q = this; +} + +/*! + Constructs a QFileSystemIterator that can iterate over \a path, with no name + filtering and \a filters for entry filtering. You can pass options via \a + flags to decide how the directory should be iterated. + + By default, \a filters is QDir::NoFilter, and \a flags is NoIteratorFlags, + which provides the same behavior as in QDir::entryList(). + + \sa atEnd(), next(), IteratorFlags +*/ +QFileSystemIterator::QFileSystemIterator(const QString &path, QDir::Filters filters, IteratorFlags flags) + : d(new QFileSystemIteratorPrivate(path, QStringList(QLatin1String("*")), filters, flags)) +{ + d->q = this; +} + +/*! + Constructs a QFileSystemIterator that can iterate over \a path. You can pass + options via \a flags to decide how the directory should be iterated. + + By default, \a flags is NoIteratorFlags, which provides the same behavior + as in QDir::entryList(). + + \sa atEnd(), next(), IteratorFlags +*/ +QFileSystemIterator::QFileSystemIterator(const QString &path, IteratorFlags flags) + : d(new QFileSystemIteratorPrivate(path, QStringList(QLatin1String("*")), QDir::NoFilter, flags)) +{ + d->q = this; +} + +/*! + Constructs a QFileSystemIterator that can iterate over \a path, using \a + nameFilters and \a filters. You can pass options via \a flags to decide + how the directory should be iterated. + + By default, \a flags is NoIteratorFlags, which provides the same behavior + as QDir::entryList(). + + \sa atEnd(), next(), IteratorFlags +*/ +QFileSystemIterator::QFileSystemIterator(const QString &path, const QStringList &nameFilters, + QDir::Filters filters, IteratorFlags flags) + : d(new QFileSystemIteratorPrivate(path, nameFilters, filters, flags)) +{ + d->q = this; +} + +/*! + Destroys the QFileSystemIterator. +*/ +QFileSystemIterator::~QFileSystemIterator() +{ + delete d; +} + +/*! + Advances the iterator to the next entry, and returns the file path of this + new entry. If atEnd() returns true, this function does nothing, and + returns a null QString. + + You can call fileName() or filePath() to get the current entry file name + or path, or fileInfo() to get a QFileInfo for the current entry. + + \sa hasNext(), fileName(), filePath(), fileInfo() +*/ +void QFileSystemIterator::next() +{ + d->advance(); +} + +/*! + Returns true if there is at least one more entry in the directory; + otherwise, false is returned. + + \sa next(), fileName(), filePath(), fileInfo() +*/ +bool QFileSystemIterator::atEnd() const +{ + return d->atEnd(); +} + +/*! + Returns the file name for the current directory entry, without the path + prepended. If the current entry is invalid (i.e., isValid() returns + false), a null QString is returned. + + This function is provided for the convenience when iterating single + directories. For recursive iteration, you should call filePath() or + fileInfo() instead. + + \sa filePath(), fileInfo() +*/ +QString QFileSystemIterator::fileName() const +{ + if (d->atEnd() || !d->m_entry) + return QString(); + if (d->m_currentDirShown == QFileSystemIteratorPrivate::ShowDir) + return QString(); + if (d->m_currentDirShown == QFileSystemIteratorPrivate::ShowDotDir) + return QLatin1String("@"); + if (d->m_currentDirShown == QFileSystemIteratorPrivate::ShowDotDotDir) + return QLatin1String("@@"); +#ifdef Q_OS_WIN + return QString::fromWCharArray(d->m_entry->cFileName); +#else + return QString::fromLocal8Bit(d->m_entry->d_name); +#endif +} + +/*! + Returns the full file path for the current directory entry. If the current + entry is invalid (i.e., isValid() returns false), a null QString is + returned. + + \sa fileInfo(), fileName() +*/ +QString QFileSystemIterator::filePath() const +{ + if (d->atEnd()) + return QString(); + QByteArray ba = d->m_dirPaths.top(); + if (d->m_currentDirShown == QFileSystemIteratorPrivate::ShowDotDir) + ba += "/."; + else if (d->m_currentDirShown == QFileSystemIteratorPrivate::ShowDotDotDir) + ba += "/.."; + else if (d->m_entry) { + ba += '/'; +#ifdef Q_OS_WIN + ba += QString::fromWCharArray(d->m_entry->cFileName); +#else + ba += d->m_entry->d_name; +#endif + } + return QString::fromLocal8Bit(ba); +} + +/*! + Returns a QFileInfo for the current directory entry. If the current entry + is invalid (i.e., isValid() returns false), a null QFileInfo is returned. + + \sa filePath(), fileName() +*/ +QFileInfo QFileSystemIterator::fileInfo() const +{ + return QFileInfo(filePath()); +} + +/*! + Returns the base directory of the iterator. +*/ +QString QFileSystemIterator::path() const +{ + return QString::fromLocal8Bit(d->m_dirPaths.top()); +} + +QT_END_NAMESPACE diff --git a/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.h b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.h new file mode 100644 index 0000000..4aad3a1 --- /dev/null +++ b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFILESYSTEMITERATOR_H +#define QFILESYSTEMITERATOR_H + +#include <QtCore/qdir.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class QFileSystemIteratorPrivate; +class //Q_CORE_EXPORT +QFileSystemIterator +{ +public: + enum IteratorFlag { + NoIteratorFlags = 0x0, + FollowSymlinks = 0x1, + Subdirectories = 0x2 + }; + Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag) + + QFileSystemIterator(const QDir &dir, IteratorFlags flags = NoIteratorFlags); + QFileSystemIterator(const QString &path, + IteratorFlags flags = NoIteratorFlags); + QFileSystemIterator(const QString &path, + QDir::Filters filter, + IteratorFlags flags = NoIteratorFlags); + QFileSystemIterator(const QString &path, + const QStringList &nameFilters, + QDir::Filters filters = QDir::NoFilter, + IteratorFlags flags = NoIteratorFlags); + + virtual ~QFileSystemIterator(); + + void next(); + bool atEnd() const; + + QString fileName() const; + QString filePath() const; + QFileInfo fileInfo() const; + QString path() const; + +private: + Q_DISABLE_COPY(QFileSystemIterator) + + QFileSystemIteratorPrivate *d; + friend class QDir; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QFileSystemIterator::IteratorFlags) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/tests/benchmarks/corelib/io/qfile/main.cpp b/tests/benchmarks/corelib/io/qfile/main.cpp new file mode 100644 index 0000000..103b77c --- /dev/null +++ b/tests/benchmarks/corelib/io/qfile/main.cpp @@ -0,0 +1,675 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDebug> +#include <QTemporaryFile> +#include <QFSFileEngine> +#include <QString> +#include <QDirIterator> + +#include <qtest.h> + +#include <stdio.h> + +#ifdef Q_OS_WIN +# include <windows.h> +# include <atlbase.h> +#endif + +#define BUFSIZE 1024*512 +#define FACTOR 1024*512 +#define TF_SIZE FACTOR*81 + +// 10 predefined (but random() seek positions +// hardcoded to be comparable over several runs +const int seekpos[] = {TF_SIZE*0.52, + TF_SIZE*0.23, + TF_SIZE*0.73, + TF_SIZE*0.77, + TF_SIZE*0.80, + TF_SIZE*0.12, + TF_SIZE*0.53, + TF_SIZE*0.21, + TF_SIZE*0.27, + TF_SIZE*0.78}; + +const int sp_size = sizeof(seekpos)/sizeof(int); + +class tst_qfile: public QObject +{ +Q_ENUMS(BenchmarkType) +Q_OBJECT +public: + enum BenchmarkType { + QFileBenchmark = 1, + QFSFileEngineBenchmark, + Win32Benchmark, + PosixBenchmark, + QFileFromPosixBenchmark + }; +private slots: + void initTestCase(); + void cleanupTestCase(); + + void open_data(); + void open(); + void seek_data(); + void seek(); + + void readSmallFiles_QFile(); + void readSmallFiles_QFSFileEngine(); + void readSmallFiles_posix(); + void readSmallFiles_Win32(); + + void readSmallFiles_QFile_data(); + void readSmallFiles_QFSFileEngine_data(); + void readSmallFiles_posix_data(); + void readSmallFiles_Win32_data(); + + void readBigFile_QFile_data(); + void readBigFile_QFSFileEngine_data(); + void readBigFile_posix_data(); + void readBigFile_Win32_data(); + + void readBigFile_QFile(); + void readBigFile_QFSFileEngine(); + void readBigFile_posix(); + void readBigFile_Win32(); + +private: + void readBigFile_data(BenchmarkType type, QIODevice::OpenModeFlag t, QIODevice::OpenModeFlag b); + void readBigFile(); + void readSmallFiles_data(BenchmarkType type, QIODevice::OpenModeFlag t, QIODevice::OpenModeFlag b); + void readSmallFiles(); + void createFile(); + void fillFile(int factor=FACTOR); + void removeFile(); + void createSmallFiles(); + void removeSmallFiles(); + QString filename; + QString tmpDirName; +}; + +Q_DECLARE_METATYPE(tst_qfile::BenchmarkType) +Q_DECLARE_METATYPE(QIODevice::OpenMode) +Q_DECLARE_METATYPE(QIODevice::OpenModeFlag) + +void tst_qfile::createFile() +{ + removeFile(); // Cleanup in case previous test case aborted before cleaning up + + QTemporaryFile tmpFile; + tmpFile.setAutoRemove(false); + if (!tmpFile.open()) + ::exit(1); + filename = tmpFile.fileName(); + tmpFile.close(); +} + +void tst_qfile::removeFile() +{ + if (!filename.isEmpty()) + QFile::remove(filename); +} + +void tst_qfile::fillFile(int factor) +{ + QFile tmpFile(filename); + tmpFile.open(QIODevice::WriteOnly); + //for (int row=0; row<factor; ++row) { + // tmpFile.write(QByteArray().fill('0'+row%('0'-'z'), 80)); + // tmpFile.write("\n"); + //} + tmpFile.seek(factor*80); + tmpFile.putChar('\n'); + tmpFile.close(); + // let IO settle + QTest::qSleep(2000); +} + +void tst_qfile::initTestCase() +{ +} + +void tst_qfile::cleanupTestCase() +{ +} + +void tst_qfile::readBigFile_QFile() { readBigFile(); } +void tst_qfile::readBigFile_QFSFileEngine() { readBigFile(); } +void tst_qfile::readBigFile_posix() { readBigFile(); } +void tst_qfile::readBigFile_Win32() { readBigFile(); } + +void tst_qfile::readBigFile_QFile_data() +{ + readBigFile_data(QFileBenchmark, QIODevice::NotOpen, QIODevice::NotOpen); + readBigFile_data(QFileBenchmark, QIODevice::NotOpen, QIODevice::Unbuffered); + readBigFile_data(QFileBenchmark, QIODevice::Text, QIODevice::NotOpen); + readBigFile_data(QFileBenchmark, QIODevice::Text, QIODevice::Unbuffered); + +} + +void tst_qfile::readBigFile_QFSFileEngine_data() +{ + readBigFile_data(QFSFileEngineBenchmark, QIODevice::NotOpen, QIODevice::NotOpen); + readBigFile_data(QFSFileEngineBenchmark, QIODevice::NotOpen, QIODevice::Unbuffered); + readBigFile_data(QFSFileEngineBenchmark, QIODevice::Text, QIODevice::NotOpen); + readBigFile_data(QFSFileEngineBenchmark, QIODevice::Text, QIODevice::Unbuffered); +} + +void tst_qfile::readBigFile_posix_data() +{ + readBigFile_data(PosixBenchmark, QIODevice::NotOpen, QIODevice::NotOpen); +} + +void tst_qfile::readBigFile_Win32_data() +{ + readBigFile_data(Win32Benchmark, QIODevice::NotOpen, QIODevice::NotOpen); +} + + +void tst_qfile::readBigFile_data(BenchmarkType type, QIODevice::OpenModeFlag t, QIODevice::OpenModeFlag b) +{ + QTest::addColumn<tst_qfile::BenchmarkType>("testType"); + QTest::addColumn<int>("blockSize"); + QTest::addColumn<QFile::OpenModeFlag>("textMode"); + QTest::addColumn<QFile::OpenModeFlag>("bufferedMode"); + + const int bs[] = {1024, 1024*2, 1024*8, 1024*16, 1024*32,1024*512}; + int bs_entries = sizeof(bs)/sizeof(const int); + + QString flagstring; + if (t & QIODevice::Text) flagstring += "textMode "; + if (b & QIODevice::Unbuffered) flagstring += "unbuffered "; + if (flagstring.isEmpty()) flagstring = "none"; + + for (int i=0; i<bs_entries; ++i) + QTest::newRow((QString("BS: %1, Flags: %2" )).arg(bs[i]).arg(flagstring).toLatin1().constData()) << type << bs[i] << t << b; +} + +void tst_qfile::readBigFile() +{ + QFETCH(tst_qfile::BenchmarkType, testType); + QFETCH(int, blockSize); + QFETCH(QFile::OpenModeFlag, textMode); + QFETCH(QFile::OpenModeFlag, bufferedMode); + +#ifndef Q_OS_WIN + if (testType == Win32Benchmark) + QSKIP("This is Windows only benchmark.", SkipSingle); +#endif + + char *buffer = new char[BUFSIZE]; + createFile(); + fillFile(); + + switch (testType) { + case(QFileBenchmark): { + QFile file(filename); + file.open(QIODevice::ReadOnly|textMode|bufferedMode); + QBENCHMARK { + while(!file.atEnd()) + file.read(blockSize); + file.reset(); + } + file.close(); + } + break; + case(QFSFileEngineBenchmark): { + QFSFileEngine fse(filename); + fse.open(QIODevice::ReadOnly|textMode|bufferedMode); + QBENCHMARK { + //qWarning() << fse.supportsExtension(QAbstractFileEngine::AtEndExtension); + while(fse.read(buffer, blockSize)); + fse.seek(0); + } + fse.close(); + } + break; + case(PosixBenchmark): { + QByteArray data = filename.toLocal8Bit(); + const char* cfilename = data.constData(); + FILE* cfile = ::fopen(cfilename, "rb"); + QBENCHMARK { + while(!feof(cfile)) + ::fread(buffer, blockSize, 1, cfile); + ::fseek(cfile, 0, SEEK_SET); + } + ::fclose(cfile); + } + break; + case(QFileFromPosixBenchmark): { + // No gain in benchmarking this case + } + break; + case(Win32Benchmark): { +#ifdef Q_OS_WIN + HANDLE hndl; + + // ensure we don't account string conversion + wchar_t* cfilename = (wchar_t*)filename.utf16(); + + hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); + Q_ASSERT(hndl); + wchar_t* nativeBuffer = new wchar_t[BUFSIZE]; + DWORD numberOfBytesRead; + + QBENCHMARK { + do { + ReadFile(hndl, nativeBuffer, blockSize, &numberOfBytesRead, NULL); + } while(numberOfBytesRead != 0); + SetFilePointer(hndl, 0, NULL, FILE_BEGIN); + } + delete[] nativeBuffer; + CloseHandle(hndl); +#else + QFAIL("Not running on a non-Windows platform!"); +#endif + } + break; + } + + removeFile(); + delete[] buffer; +} + +void tst_qfile::seek_data() +{ + QTest::addColumn<tst_qfile::BenchmarkType>("testType"); + QTest::newRow("QFile") << QFileBenchmark; + QTest::newRow("QFSFileEngine") << QFSFileEngineBenchmark; + QTest::newRow("Posix FILE*") << PosixBenchmark; +#ifdef Q_OS_WIN + QTest::newRow("Win32 API") << Win32Benchmark; +#endif +} + +void tst_qfile::seek() +{ + QFETCH(tst_qfile::BenchmarkType, testType); + int i = 0; + + createFile(); + fillFile(); + + switch (testType) { + case(QFileBenchmark): { + QFile file(filename); + file.open(QIODevice::ReadOnly); + QBENCHMARK { + i=(i+1)%sp_size; + file.seek(seekpos[i]); + } + file.close(); + } + break; + case(QFSFileEngineBenchmark): { + QFSFileEngine fse(filename); + fse.open(QIODevice::ReadOnly); + QBENCHMARK { + i=(i+1)%sp_size; + fse.seek(seekpos[i]); + } + fse.close(); + } + break; + case(PosixBenchmark): { + QByteArray data = filename.toLocal8Bit(); + const char* cfilename = data.constData(); + FILE* cfile = ::fopen(cfilename, "rb"); + QBENCHMARK { + i=(i+1)%sp_size; + ::fseek(cfile, seekpos[i], SEEK_SET); + } + ::fclose(cfile); + } + break; + case(QFileFromPosixBenchmark): { + // No gain in benchmarking this case + } + break; + case(Win32Benchmark): { +#ifdef Q_OS_WIN + HANDLE hndl; + + // ensure we don't account string conversion + wchar_t* cfilename = (wchar_t*)filename.utf16(); + + hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); + Q_ASSERT(hndl); + QBENCHMARK { + i=(i+1)%sp_size; + SetFilePointer(hndl, seekpos[i], NULL, 0); + } + CloseHandle(hndl); +#else + QFAIL("Not running on a Windows plattform!"); +#endif + } + break; + } + + removeFile(); +} + +void tst_qfile::open_data() +{ + QTest::addColumn<tst_qfile::BenchmarkType>("testType"); + QTest::newRow("QFile") << QFileBenchmark; + QTest::newRow("QFSFileEngine") << QFSFileEngineBenchmark; + QTest::newRow("Posix FILE*") << PosixBenchmark; + QTest::newRow("QFile from FILE*") << QFileFromPosixBenchmark; +#ifdef Q_OS_WIN + QTest::newRow("Win32 API") << Win32Benchmark; +#endif +} + +void tst_qfile::open() +{ + QFETCH(tst_qfile::BenchmarkType, testType); + + createFile(); + + switch (testType) { + case(QFileBenchmark): { + QBENCHMARK { + QFile file( filename ); + file.open( QIODevice::ReadOnly ); + file.close(); + } + } + break; + case(QFSFileEngineBenchmark): { + QBENCHMARK { + QFSFileEngine fse(filename); + fse.open(QIODevice::ReadOnly); + fse.close(); + } + } + break; + + case(PosixBenchmark): { + // ensure we don't account toLocal8Bit() + QByteArray data = filename.toLocal8Bit(); + const char* cfilename = data.constData(); + + QBENCHMARK { + FILE* cfile = ::fopen(cfilename, "rb"); + ::fclose(cfile); + } + } + break; + case(QFileFromPosixBenchmark): { + // ensure we don't account toLocal8Bit() + QByteArray data = filename.toLocal8Bit(); + const char* cfilename = data.constData(); + FILE* cfile = ::fopen(cfilename, "rb"); + + QBENCHMARK { + QFile file; + file.open(cfile, QIODevice::ReadOnly); + file.close(); + } + ::fclose(cfile); + } + break; + case(Win32Benchmark): { +#ifdef Q_OS_WIN + HANDLE hndl; + + // ensure we don't account string conversion + wchar_t* cfilename = (wchar_t*)filename.utf16(); + + QBENCHMARK { + hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); + Q_ASSERT(hndl); + CloseHandle(hndl); + } +#else + QFAIL("Not running on a non-Windows platform!"); +#endif + } + break; + } + + removeFile(); +} + + +void tst_qfile::readSmallFiles_QFile() { readSmallFiles(); } +void tst_qfile::readSmallFiles_QFSFileEngine() { readSmallFiles(); } +void tst_qfile::readSmallFiles_posix() { readSmallFiles(); } +void tst_qfile::readSmallFiles_Win32() { readSmallFiles(); } + +void tst_qfile::readSmallFiles_QFile_data() +{ + readSmallFiles_data(QFileBenchmark, QIODevice::NotOpen, QIODevice::NotOpen); + readSmallFiles_data(QFileBenchmark, QIODevice::NotOpen, QIODevice::Unbuffered); + readSmallFiles_data(QFileBenchmark, QIODevice::Text, QIODevice::NotOpen); + readSmallFiles_data(QFileBenchmark, QIODevice::Text, QIODevice::Unbuffered); + +} + +void tst_qfile::readSmallFiles_QFSFileEngine_data() +{ + readSmallFiles_data(QFSFileEngineBenchmark, QIODevice::NotOpen, QIODevice::NotOpen); + readSmallFiles_data(QFSFileEngineBenchmark, QIODevice::NotOpen, QIODevice::Unbuffered); + readSmallFiles_data(QFSFileEngineBenchmark, QIODevice::Text, QIODevice::NotOpen); + readSmallFiles_data(QFSFileEngineBenchmark, QIODevice::Text, QIODevice::Unbuffered); +} + +void tst_qfile::readSmallFiles_posix_data() +{ + readSmallFiles_data(PosixBenchmark, QIODevice::NotOpen, QIODevice::NotOpen); +} + +void tst_qfile::readSmallFiles_Win32_data() +{ + readSmallFiles_data(Win32Benchmark, QIODevice::NotOpen, QIODevice::NotOpen); +} + + +void tst_qfile::readSmallFiles_data(BenchmarkType type, QIODevice::OpenModeFlag t, QIODevice::OpenModeFlag b) +{ + QTest::addColumn<tst_qfile::BenchmarkType>("testType"); + QTest::addColumn<int>("blockSize"); + QTest::addColumn<QFile::OpenModeFlag>("textMode"); + QTest::addColumn<QFile::OpenModeFlag>("bufferedMode"); + + const int bs[] = {1024, 1024*2, 1024*8, 1024*16, 1024*32,1024*512}; + int bs_entries = sizeof(bs)/sizeof(const int); + + QString flagstring; + if (t & QIODevice::Text) flagstring += "textMode "; + if (b & QIODevice::Unbuffered) flagstring += "unbuffered "; + if (flagstring.isEmpty()) flagstring = "none"; + + for (int i=0; i<bs_entries; ++i) + QTest::newRow((QString("BS: %1, Flags: %2" )).arg(bs[i]).arg(flagstring).toLatin1().constData()) << type << bs[i] << t << b; + +} + +void tst_qfile::createSmallFiles() +{ + QDir dir = QDir::temp(); + dir.mkdir("tst"); + dir.cd("tst"); + tmpDirName = dir.absolutePath(); + +#ifdef Q_OS_SYMBIAN + for (int i = 0; i < 100; ++i) +#else + for (int i = 0; i < 1000; ++i) +#endif + { + QFile f(tmpDirName+"/"+QString::number(i)); + f.open(QIODevice::WriteOnly); + f.seek(511); + f.putChar('\n'); + f.close(); + } +} + +void tst_qfile::removeSmallFiles() +{ + QDirIterator it(tmpDirName, QDirIterator::FollowSymlinks); + while (it.hasNext()) + QFile::remove(it.next()); + QDir::temp().rmdir("tst"); +} + + +void tst_qfile::readSmallFiles() +{ + QFETCH(tst_qfile::BenchmarkType, testType); + QFETCH(int, blockSize); + QFETCH(QFile::OpenModeFlag, textMode); + QFETCH(QFile::OpenModeFlag, bufferedMode); + +#ifndef Q_OS_WIN + if (testType == Win32Benchmark) + QSKIP("This is Windows only benchmark.", SkipSingle); +#endif + + createSmallFiles(); + + QDir dir(tmpDirName); + const QStringList files = dir.entryList(QDir::NoDotAndDotDot|QDir::NoSymLinks|QDir::Files); + char *buffer = new char[BUFSIZE]; + + switch (testType) { + case(QFileBenchmark): { + QList<QFile*> fileList; + Q_FOREACH(QString file, files) { + QFile *f = new QFile(tmpDirName+ "/" + file); + f->open(QIODevice::ReadOnly|textMode|bufferedMode); + fileList.append(f); + } + + QBENCHMARK { + Q_FOREACH(QFile *file, fileList) { + while (!file->atEnd()) { + file->read(buffer, blockSize); + } + } + } + + Q_FOREACH(QFile *file, fileList) { + file->close(); + delete file; + } + } + break; + case(QFSFileEngineBenchmark): { + QList<QFSFileEngine*> fileList; + Q_FOREACH(QString file, files) { + QFSFileEngine *fse = new QFSFileEngine(tmpDirName+ "/" + file); + fse->open(QIODevice::ReadOnly|textMode|bufferedMode); + fileList.append(fse); + } + + QBENCHMARK { + Q_FOREACH(QFSFileEngine *fse, fileList) { + while (fse->read(buffer, blockSize)); + } + } + + Q_FOREACH(QFSFileEngine *fse, fileList) { + fse->close(); + delete fse; + } + } + break; + case(PosixBenchmark): { + QList<FILE*> fileList; + Q_FOREACH(QString file, files) { + fileList.append(::fopen(QFile::encodeName(tmpDirName+ "/" + file).constData(), "rb")); + } + + QBENCHMARK { + Q_FOREACH(FILE* cfile, fileList) { + while(!feof(cfile)) + ::fread(buffer, blockSize, 1, cfile); + ::fseek(cfile, 0, SEEK_SET); + } + } + + Q_FOREACH(FILE* cfile, fileList) { + ::fclose(cfile); + } + } + break; + case(QFileFromPosixBenchmark): { + // No gain in benchmarking this case + } + break; + case(Win32Benchmark): { +#ifdef Q_OS_WIN + HANDLE hndl; + + // ensure we don't account string conversion + wchar_t* cfilename = (wchar_t*)filename.utf16(); + + hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); + Q_ASSERT(hndl); + wchar_t* nativeBuffer = new wchar_t[BUFSIZE]; + DWORD numberOfBytesRead; + QBENCHMARK { + do { + ReadFile(hndl, nativeBuffer, blockSize, &numberOfBytesRead, NULL); + } while(numberOfBytesRead != 0); + } + delete nativeBuffer; + CloseHandle(hndl); +#else + QFAIL("Not running on a non-Windows platform!"); +#endif + } + break; + } + + removeSmallFiles(); + delete[] buffer; +} + +QTEST_MAIN(tst_qfile) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/io/qfile/qfile.pro b/tests/benchmarks/corelib/io/qfile/qfile.pro new file mode 100644 index 0000000..99505c3 --- /dev/null +++ b/tests/benchmarks/corelib/io/qfile/qfile.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qfile +QT -= gui +win32: DEFINES+= _CRT_SECURE_NO_WARNINGS + +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/io/qfileinfo/main.cpp b/tests/benchmarks/corelib/io/qfileinfo/main.cpp new file mode 100644 index 0000000..025787f --- /dev/null +++ b/tests/benchmarks/corelib/io/qfileinfo/main.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QDebug> +#include <qtest.h> +#include <QtTest/QtTest> +#include <QtCore/QCoreApplication> +#include <QtCore/QFileInfo> + +#include "private/qfsfileengine_p.h" + +class qfileinfo : public QObject +{ + Q_OBJECT +private slots: + void canonicalFileNamePerformance(); + + void initTestCase(); + void cleanupTestCase(); +public: + qfileinfo() : QObject() {}; +}; + +void qfileinfo::initTestCase() +{ +} + +void qfileinfo::cleanupTestCase() +{ +} + +void qfileinfo::canonicalFileNamePerformance() +{ + QString appPath = QCoreApplication::applicationFilePath(); + QFSFileEnginePrivate::canonicalized(appPath); // warmup + QFSFileEnginePrivate::canonicalized(appPath); // more warmup + QBENCHMARK { + for (int i = 0; i < 5000; i++) { + QFSFileEnginePrivate::canonicalized(appPath); + } + } +} + +QTEST_MAIN(qfileinfo) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/io/qfileinfo/qfileinfo.pro b/tests/benchmarks/corelib/io/qfileinfo/qfileinfo.pro new file mode 100644 index 0000000..295cb50 --- /dev/null +++ b/tests/benchmarks/corelib/io/qfileinfo/qfileinfo.pro @@ -0,0 +1,12 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = qfileinfo +DEPENDPATH += . +INCLUDEPATH += . + +QT -= gui + +CONFIG += release + +# Input +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/io/qiodevice/main.cpp b/tests/benchmarks/corelib/io/qiodevice/main.cpp new file mode 100644 index 0000000..4af697c --- /dev/null +++ b/tests/benchmarks/corelib/io/qiodevice/main.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QDebug> +#include <QIODevice> +#include <QFile> +#include <QString> + +#include <qtest.h> + + +class tst_qiodevice : public QObject +{ + Q_OBJECT +private slots: + void read_old(); + void read_old_data() { read_data(); } + //void read_new(); + //void read_new_data() { read_data(); } +private: + void read_data(); +}; + + +void tst_qiodevice::read_data() +{ + QTest::addColumn<qint64>("size"); + QTest::newRow("10k") << qint64(10 * 1024); + QTest::newRow("100k") << qint64(100 * 1024); + QTest::newRow("1000k") << qint64(1000 * 1024); + QTest::newRow("10000k") << qint64(10000 * 1024); +#ifndef Q_OS_SYMBIAN // Symbian devices don't (yet) have enough available RAM to run these + QTest::newRow("100000k") << qint64(100000 * 1024); + QTest::newRow("1000000k") << qint64(1000000 * 1024); +#endif +} + +void tst_qiodevice::read_old() +{ + QFETCH(qint64, size); + + QString name = "tmp" + QString::number(size); + + { + QFile file(name); + file.open(QIODevice::WriteOnly); + file.seek(size); + file.write("x", 1); + file.close(); + } + + QBENCHMARK { + QFile file(name); + file.open(QIODevice::ReadOnly); + QByteArray ba; + qint64 s = size - 1024; + file.seek(512); + ba = file.read(s); // crash happens during this read / assignment operation + } + + { + QFile file(name); + file.remove(); + } +} + + +QTEST_MAIN(tst_qiodevice) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/io/qiodevice/qiodevice.pro b/tests/benchmarks/corelib/io/qiodevice/qiodevice.pro new file mode 100755 index 0000000..749a4d6 --- /dev/null +++ b/tests/benchmarks/corelib/io/qiodevice/qiodevice.pro @@ -0,0 +1,13 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qiodevice +TARGET.EPOCHEAPSIZE = 0x100000 0x2000000 +DEPENDPATH += . +INCLUDEPATH += . + +QT -= gui + +CONFIG += release + +# Input +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/io/qtemporaryfile/main.cpp b/tests/benchmarks/corelib/io/qtemporaryfile/main.cpp new file mode 100644 index 0000000..8b71189 --- /dev/null +++ b/tests/benchmarks/corelib/io/qtemporaryfile/main.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QDebug> +#include <QIODevice> +#include <QFile> +#include <QString> +#include <QTemporaryFile> +#include <qtest.h> + + +class tst_qtemporaryfile : public QObject +{ + Q_OBJECT +private slots: + void openclose_data(); + void openclose(); + void readwrite_data() { openclose_data(); } + void readwrite(); + +private: +}; + +void tst_qtemporaryfile::openclose_data() +{ + QTest::addColumn<qint64>("amount"); + QTest::newRow("100") << qint64(100); + QTest::newRow("1000") << qint64(1000); + QTest::newRow("10000") << qint64(10000); +} + +void tst_qtemporaryfile::openclose() +{ + QFETCH(qint64, amount); + + QBENCHMARK { + for (qint64 i = 0; i < amount; ++i) { + QTemporaryFile file; + file.open(); + file.close(); + } + } +} + +void tst_qtemporaryfile::readwrite() +{ + QFETCH(qint64, amount); + + const int dataSize = 4096; + QByteArray data; + data.fill('a', dataSize); + QBENCHMARK { + for (qint64 i = 0; i < amount; ++i) { + QTemporaryFile file; + file.open(); + file.write(data); + file.seek(0); + file.read(dataSize); + file.close(); + } + } +} + +QTEST_MAIN(tst_qtemporaryfile) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/io/qtemporaryfile/qtemporaryfile.pro b/tests/benchmarks/corelib/io/qtemporaryfile/qtemporaryfile.pro new file mode 100644 index 0000000..c1b04f4 --- /dev/null +++ b/tests/benchmarks/corelib/io/qtemporaryfile/qtemporaryfile.pro @@ -0,0 +1,12 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qtemporaryfile +DEPENDPATH += . +INCLUDEPATH += . + +QT -= gui + +CONFIG += release + +# Input +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/kernel/events/events.pro b/tests/benchmarks/corelib/kernel/events/events.pro new file mode 100644 index 0000000..adf2317 --- /dev/null +++ b/tests/benchmarks/corelib/kernel/events/events.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_events +DEPENDPATH += . +INCLUDEPATH += . +# Input +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/kernel/events/main.cpp b/tests/benchmarks/corelib/kernel/events/main.cpp new file mode 100644 index 0000000..0dd2c18 --- /dev/null +++ b/tests/benchmarks/corelib/kernel/events/main.cpp @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtCore> + +#include <qtest.h> +#include <qtesteventloop.h> + +class PingPong : public QObject +{ +public: + void setPeer(QObject *peer); + void resetCounter() {m_counter = 100;} + +protected: + bool event(QEvent *e); + +private: + QObject *m_peer; + int m_counter; +}; + +void PingPong::setPeer(QObject *peer) +{ + m_peer = peer; + m_counter = 100; +} + +bool PingPong::event(QEvent *) +{ + --m_counter; + if (m_counter > 0) { + QEvent *e = new QEvent(QEvent::User); + QCoreApplication::postEvent(m_peer, e); + } else { + QTestEventLoop::instance().exitLoop(); + } + return true; +} + +class EventTester : public QObject +{ +public: + int foo(int bar); + +protected: + bool event(QEvent *e); +}; + +bool EventTester::event(QEvent *e) +{ + if (e->type() == QEvent::User+1) + return foo(e->type()) != 0; + return false; +} + +int EventTester::foo(int bar) +{ + return bar + 1; +} + +class EventsBench : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void noEvent(); + void sendEvent_data(); + void sendEvent(); + void postEvent_data(); + void postEvent(); +}; + +void EventsBench::initTestCase() +{ +} + +void EventsBench::cleanupTestCase() +{ +} + +void EventsBench::noEvent() +{ + EventTester tst; + int val = 0; + QBENCHMARK { + val += tst.foo(1); + } +} + +void EventsBench::sendEvent_data() +{ + QTest::addColumn<bool>("filterEvents"); + QTest::newRow("no eventfilter") << false; + QTest::newRow("eventfilter") << true; +} + +void EventsBench::sendEvent() +{ + QFETCH(bool, filterEvents); + EventTester tst; + if (filterEvents) + tst.installEventFilter(this); + QEvent evt(QEvent::Type(QEvent::User+1)); + QBENCHMARK { + QCoreApplication::sendEvent(&tst, &evt); + } +} + +void EventsBench::postEvent_data() +{ + QTest::addColumn<bool>("filterEvents"); + // The first time an eventloop is executed, the case runs radically slower at least + // on some platforms, so test the "no eventfilter" case to get a comparable results + // with the "eventfilter" case. + QTest::newRow("first time, no eventfilter") << false; + QTest::newRow("no eventfilter") << false; + QTest::newRow("eventfilter") << true; +} + +void EventsBench::postEvent() +{ + QFETCH(bool, filterEvents); + PingPong ping; + PingPong pong; + ping.setPeer(&pong); + pong.setPeer(&ping); + if (filterEvents) { + ping.installEventFilter(this); + pong.installEventFilter(this); + } + + QBENCHMARK { + // In case multiple iterations are done, event needs to be created inside the QBENCHMARK, + // or it gets deleted once first iteration exits and can cause a crash. Similarly, + // ping and pong need their counters reset. + QEvent *e = new QEvent(QEvent::User); + ping.resetCounter(); + pong.resetCounter(); + QCoreApplication::postEvent(&ping, e); + QTestEventLoop::instance().enterLoop( 61 ); + } +} + +QTEST_MAIN(EventsBench) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/kernel/kernel.pro b/tests/benchmarks/corelib/kernel/kernel.pro new file mode 100644 index 0000000..91cf3c5 --- /dev/null +++ b/tests/benchmarks/corelib/kernel/kernel.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs +SUBDIRS = \ + events \ + qmetaobject \ + qobject \ + qvariant diff --git a/tests/benchmarks/corelib/kernel/qmetaobject/main.cpp b/tests/benchmarks/corelib/kernel/qmetaobject/main.cpp new file mode 100644 index 0000000..eef6020 --- /dev/null +++ b/tests/benchmarks/corelib/kernel/qmetaobject/main.cpp @@ -0,0 +1,264 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtCore> +#include <QtGui> +#include <qtest.h> + +class LotsOfSignals : public QObject +{ + Q_OBJECT +public: + LotsOfSignals() {} + +signals: + void extraSignal1(); + void extraSignal2(); + void extraSignal3(); + void extraSignal4(); + void extraSignal5(); + void extraSignal6(); + void extraSignal7(); + void extraSignal8(); + void extraSignal9(); + void extraSignal10(); + void extraSignal12(); + void extraSignal13(); + void extraSignal14(); + void extraSignal15(); + void extraSignal16(); + void extraSignal17(); + void extraSignal18(); + void extraSignal19(); + void extraSignal20(); + void extraSignal21(); + void extraSignal22(); + void extraSignal23(); + void extraSignal24(); + void extraSignal25(); + void extraSignal26(); + void extraSignal27(); + void extraSignal28(); + void extraSignal29(); + void extraSignal30(); + void extraSignal31(); + void extraSignal32(); + void extraSignal33(); + void extraSignal34(); + void extraSignal35(); + void extraSignal36(); + void extraSignal37(); + void extraSignal38(); + void extraSignal39(); + void extraSignal40(); + void extraSignal41(); + void extraSignal42(); + void extraSignal43(); + void extraSignal44(); + void extraSignal45(); + void extraSignal46(); + void extraSignal47(); + void extraSignal48(); + void extraSignal49(); + void extraSignal50(); + void extraSignal51(); + void extraSignal52(); + void extraSignal53(); + void extraSignal54(); + void extraSignal55(); + void extraSignal56(); + void extraSignal57(); + void extraSignal58(); + void extraSignal59(); + void extraSignal60(); + void extraSignal61(); + void extraSignal62(); + void extraSignal63(); + void extraSignal64(); + void extraSignal65(); + void extraSignal66(); + void extraSignal67(); + void extraSignal68(); + void extraSignal69(); + void extraSignal70(); +}; + +class tst_qmetaobject: public QObject +{ +Q_OBJECT +private slots: + void initTestCase(); + void cleanupTestCase(); + + void indexOfProperty_data(); + void indexOfProperty(); + void indexOfMethod_data(); + void indexOfMethod(); + void indexOfSignal_data(); + void indexOfSignal(); + void indexOfSlot_data(); + void indexOfSlot(); + + void unconnected_data(); + void unconnected(); +}; + +void tst_qmetaobject::initTestCase() +{ +} + +void tst_qmetaobject::cleanupTestCase() +{ +} + +void tst_qmetaobject::indexOfProperty_data() +{ + QTest::addColumn<QByteArray>("name"); + const QMetaObject *mo = &QTreeView::staticMetaObject; + for (int i = 0; i < mo->propertyCount(); ++i) { + QMetaProperty prop = mo->property(i); + QTest::newRow(prop.name()) << QByteArray(prop.name()); + } +} + +void tst_qmetaobject::indexOfProperty() +{ + QFETCH(QByteArray, name); + const char *p = name.constData(); + const QMetaObject *mo = &QTreeView::staticMetaObject; + QBENCHMARK { + (void)mo->indexOfProperty(p); + } +} + +void tst_qmetaobject::indexOfMethod_data() +{ + QTest::addColumn<QByteArray>("method"); + const QMetaObject *mo = &QTreeView::staticMetaObject; + for (int i = 0; i < mo->methodCount(); ++i) { + QMetaMethod method = mo->method(i); + QByteArray sig = method.signature(); + QTest::newRow(sig) << sig; + } +} + +void tst_qmetaobject::indexOfMethod() +{ + QFETCH(QByteArray, method); + const char *p = method.constData(); + const QMetaObject *mo = &QTreeView::staticMetaObject; + QBENCHMARK { + (void)mo->indexOfMethod(p); + } +} + +void tst_qmetaobject::indexOfSignal_data() +{ + QTest::addColumn<QByteArray>("signal"); + const QMetaObject *mo = &QTreeView::staticMetaObject; + for (int i = 0; i < mo->methodCount(); ++i) { + QMetaMethod method = mo->method(i); + if (method.methodType() != QMetaMethod::Signal) + continue; + QByteArray sig = method.signature(); + QTest::newRow(sig) << sig; + } +} + +void tst_qmetaobject::indexOfSignal() +{ + QFETCH(QByteArray, signal); + const char *p = signal.constData(); + const QMetaObject *mo = &QTreeView::staticMetaObject; + QBENCHMARK { + (void)mo->indexOfSignal(p); + } +} + +void tst_qmetaobject::indexOfSlot_data() +{ + QTest::addColumn<QByteArray>("slot"); + const QMetaObject *mo = &QTreeView::staticMetaObject; + for (int i = 0; i < mo->methodCount(); ++i) { + QMetaMethod method = mo->method(i); + if (method.methodType() != QMetaMethod::Slot) + continue; + QByteArray sig = method.signature(); + QTest::newRow(sig) << sig; + } +} + +void tst_qmetaobject::indexOfSlot() +{ + QFETCH(QByteArray, slot); + const char *p = slot.constData(); + const QMetaObject *mo = &QTreeView::staticMetaObject; + QBENCHMARK { + (void)mo->indexOfSlot(p); + } +} + +void tst_qmetaobject::unconnected_data() +{ + QTest::addColumn<int>("signal_index"); + QTest::newRow("signal--9") << 9; + QTest::newRow("signal--32") << 32; + QTest::newRow("signal--33") << 33; + QTest::newRow("signal--64") << 64; + QTest::newRow("signal--65") << 65; + QTest::newRow("signal--70") << 70; +} + +void tst_qmetaobject::unconnected() +{ + LotsOfSignals *obj = new LotsOfSignals; + QFETCH(int, signal_index); + QVERIFY(obj->metaObject()->methodCount() == 73); + void *v; + QBENCHMARK { + //+1 because QObject has one slot + QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, signal_index+1, &v); + } + delete obj; +} + +QTEST_MAIN(tst_qmetaobject) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/kernel/qmetaobject/qmetaobject.pro b/tests/benchmarks/corelib/kernel/qmetaobject/qmetaobject.pro new file mode 100644 index 0000000..78300f6 --- /dev/null +++ b/tests/benchmarks/corelib/kernel/qmetaobject/qmetaobject.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qmetaobject + +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/kernel/qobject/main.cpp b/tests/benchmarks/corelib/kernel/qobject/main.cpp new file mode 100644 index 0000000..7f24ebd --- /dev/null +++ b/tests/benchmarks/corelib/kernel/qobject/main.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtCore> +#include <QtGui> +#include <qtest.h> +#include "object.h" +#include <qcoreapplication.h> +#include <qdatetime.h> + +enum { + CreationDeletionBenckmarkConstant = 34567, + SignalsAndSlotsBenchmarkConstant = 456789 +}; + +class QObjectBenchmark : public QObject +{ +Q_OBJECT +private slots: + void signal_slot_benchmark(); + void signal_slot_benchmark_data(); + void qproperty_benchmark_data(); + void qproperty_benchmark(); + void dynamic_property_benchmark(); + void connect_disconnect_benchmark_data(); + void connect_disconnect_benchmark(); +}; + +void QObjectBenchmark::signal_slot_benchmark_data() +{ + QTest::addColumn<int>("type"); + QTest::newRow("simple function") << 0; + QTest::newRow("single signal/slot") << 1; + QTest::newRow("multi signal/slot") << 2; +} + +void QObjectBenchmark::signal_slot_benchmark() +{ + QFETCH(int, type); + + Object singleObject; + Object multiObject; + singleObject.setObjectName("single"); + multiObject.setObjectName("multi"); + + singleObject.connect(&singleObject, SIGNAL(signal0()), SLOT(slot0())); + + multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(slot0())); + // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal1())); + multiObject.connect(&multiObject, SIGNAL(signal1()), SLOT(slot1())); + // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal2())); + multiObject.connect(&multiObject, SIGNAL(signal2()), SLOT(slot2())); + // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal3())); + multiObject.connect(&multiObject, SIGNAL(signal3()), SLOT(slot3())); + // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal4())); + multiObject.connect(&multiObject, SIGNAL(signal4()), SLOT(slot4())); + // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal5())); + multiObject.connect(&multiObject, SIGNAL(signal5()), SLOT(slot5())); + // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal6())); + multiObject.connect(&multiObject, SIGNAL(signal6()), SLOT(slot6())); + // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal7())); + multiObject.connect(&multiObject, SIGNAL(signal7()), SLOT(slot7())); + // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal8())); + multiObject.connect(&multiObject, SIGNAL(signal8()), SLOT(slot8())); + // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal9())); + multiObject.connect(&multiObject, SIGNAL(signal9()), SLOT(slot9())); + + if (type == 0) { + QBENCHMARK { + singleObject.slot0(); + } + } else if (type == 1) { + QBENCHMARK { + singleObject.emitSignal0(); + } + } else { + QBENCHMARK { + multiObject.emitSignal0(); + } + } +} + +void QObjectBenchmark::qproperty_benchmark_data() +{ + QTest::addColumn<QByteArray>("name"); + const QMetaObject *mo = &QTreeView::staticMetaObject; + for (int i = 0; i < mo->propertyCount(); ++i) { + QMetaProperty prop = mo->property(i); + QTest::newRow(prop.name()) << QByteArray(prop.name()); + } +} + +void QObjectBenchmark::qproperty_benchmark() +{ + QFETCH(QByteArray, name); + const char *p = name.constData(); + QTreeView obj; + QVariant v = obj.property(p); + QBENCHMARK { + obj.setProperty(p, v); + (void)obj.property(p); + } +} + +void QObjectBenchmark::dynamic_property_benchmark() +{ + QTreeView obj; + QBENCHMARK { + obj.setProperty("myProperty", 123); + (void)obj.property("myProperty"); + obj.setProperty("myOtherProperty", 123); + (void)obj.property("myOtherProperty"); + } +} + +void QObjectBenchmark::connect_disconnect_benchmark_data() +{ + QTest::addColumn<QByteArray>("signal"); + const QMetaObject *mo = &QTreeView::staticMetaObject; + for (int i = 0; i < mo->methodCount(); ++i) { + QMetaMethod method = mo->method(i); + if (method.methodType() != QMetaMethod::Signal) + continue; + QByteArray sig = method.signature(); + QTest::newRow(sig) << sig; + } +} + +void QObjectBenchmark::connect_disconnect_benchmark() +{ + QFETCH(QByteArray, signal); + signal.prepend('2'); + const char *p = signal.constData(); + QTreeView obj; + QBENCHMARK { + QObject::connect(&obj, p, &obj, p); + QObject::disconnect(&obj, p, &obj, p); + } +} + +QTEST_MAIN(QObjectBenchmark) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/kernel/qobject/object.cpp b/tests/benchmarks/corelib/kernel/qobject/object.cpp new file mode 100644 index 0000000..d775a32 --- /dev/null +++ b/tests/benchmarks/corelib/kernel/qobject/object.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "object.h" + +void Object::emitSignal0() +{ emit signal0(); } + +void Object::slot0() +{ } +void Object::slot1() +{ } +void Object::slot2() +{ } +void Object::slot3() +{ } +void Object::slot4() +{ } +void Object::slot5() +{ } +void Object::slot6() +{ } +void Object::slot7() +{ } +void Object::slot8() +{ } +void Object::slot9() +{ } diff --git a/tests/benchmarks/corelib/kernel/qobject/object.h b/tests/benchmarks/corelib/kernel/qobject/object.h new file mode 100644 index 0000000..7e4933f --- /dev/null +++ b/tests/benchmarks/corelib/kernel/qobject/object.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef OBJECT_H +#define OBJECT_H + +#include <qobject.h> + +class Object : public QObject +{ + Q_OBJECT +public: + void emitSignal0(); +signals: + void signal0(); + void signal1(); + void signal2(); + void signal3(); + void signal4(); + void signal5(); + void signal6(); + void signal7(); + void signal8(); + void signal9(); +public slots: + void slot0(); + void slot1(); + void slot2(); + void slot3(); + void slot4(); + void slot5(); + void slot6(); + void slot7(); + void slot8(); + void slot9(); +}; + +#endif // OBJECT_H diff --git a/tests/benchmarks/corelib/kernel/qobject/qobject.pro b/tests/benchmarks/corelib/kernel/qobject/qobject.pro new file mode 100644 index 0000000..2855de4 --- /dev/null +++ b/tests/benchmarks/corelib/kernel/qobject/qobject.pro @@ -0,0 +1,9 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qobject +DEPENDPATH += . +INCLUDEPATH += . + +# Input +HEADERS += object.h +SOURCES += main.cpp object.cpp diff --git a/tests/benchmarks/corelib/kernel/qvariant/qvariant.pro b/tests/benchmarks/corelib/kernel/qvariant/qvariant.pro new file mode 100644 index 0000000..63b5442 --- /dev/null +++ b/tests/benchmarks/corelib/kernel/qvariant/qvariant.pro @@ -0,0 +1,11 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qvariant +DEPENDPATH += . +INCLUDEPATH += . + +CONFIG += release +#CONFIG += debug + + +SOURCES += tst_qvariant.cpp diff --git a/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp new file mode 100644 index 0000000..82dc7dd --- /dev/null +++ b/tests/benchmarks/corelib/kernel/qvariant/tst_qvariant.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore> +#include <QtGui/QPixmap> +#include <qtest.h> + +#define ITERATION_COUNT 1e5 + +class tst_qvariant : public QObject +{ + Q_OBJECT +private slots: + void testBound(); + + void doubleVariantCreation(); + void floatVariantCreation(); + void rectVariantCreation(); + void stringVariantCreation(); + void pixmapVariantCreation(); + + void doubleVariantSetValue(); + void floatVariantSetValue(); + void rectVariantSetValue(); + void stringVariantSetValue(); + + void doubleVariantAssignment(); + void floatVariantAssignment(); + void rectVariantAssignment(); + void stringVariantAssignment(); +}; + +void tst_qvariant::testBound() +{ + qreal d = qreal(.5); + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + d = qBound<qreal>(0, d, 1); + } + } +} + +template <typename T> +static void variantCreation(T val) +{ + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + QVariant v(val); + } + } +} + +void tst_qvariant::doubleVariantCreation() +{ + variantCreation<double>(0.0); +} + +void tst_qvariant::floatVariantCreation() +{ + variantCreation<float>(0.0f); +} + +void tst_qvariant::rectVariantCreation() +{ + variantCreation<QRect>(QRect(1, 2, 3, 4)); +} + +void tst_qvariant::stringVariantCreation() +{ + variantCreation<QString>(QString()); +} + +void tst_qvariant::pixmapVariantCreation() +{ + variantCreation<QPixmap>(QPixmap()); +} + +template <typename T> +static void variantSetValue(T d) +{ + QVariant v; + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + qVariantSetValue(v, d); + } + } +} + +void tst_qvariant::doubleVariantSetValue() +{ + variantSetValue<double>(0.0); +} + +void tst_qvariant::floatVariantSetValue() +{ + variantSetValue<float>(0.0f); +} + +void tst_qvariant::rectVariantSetValue() +{ + variantSetValue<QRect>(QRect()); +} + +void tst_qvariant::stringVariantSetValue() +{ + variantSetValue<QString>(QString()); +} + +template <typename T> +static void variantAssignment(T d) +{ + QVariant v; + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + v = d; + } + } +} + +void tst_qvariant::doubleVariantAssignment() +{ + variantAssignment<double>(0.0); +} + +void tst_qvariant::floatVariantAssignment() +{ + variantAssignment<float>(0.0f); +} + +void tst_qvariant::rectVariantAssignment() +{ + variantAssignment<QRect>(QRect()); +} + +void tst_qvariant::stringVariantAssignment() +{ + variantAssignment<QString>(QString()); +} + +QTEST_MAIN(tst_qvariant) + +#include "tst_qvariant.moc" diff --git a/tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro b/tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro new file mode 100644 index 0000000..f9c1978 --- /dev/null +++ b/tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qthreadstorage + +SOURCES += tst_qthreadstorage.cpp + diff --git a/tests/benchmarks/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp b/tests/benchmarks/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp new file mode 100644 index 0000000..faae4d7 --- /dev/null +++ b/tests/benchmarks/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <QtCore> + +//TESTED_FILES= + +QThreadStorage<int *> dummy[8]; + +QThreadStorage<QString *> tls1; + +class tst_QThreadStorage : public QObject +{ + Q_OBJECT + +public: + tst_QThreadStorage(); + virtual ~tst_QThreadStorage(); + +public slots: + void init(); + void cleanup(); + +private slots: + void construct(); + void get(); + void set(); +}; + +tst_QThreadStorage::tst_QThreadStorage() +{ +} + +tst_QThreadStorage::~tst_QThreadStorage() +{ +} + +void tst_QThreadStorage::init() +{ + dummy[1].setLocalData(new int(5)); + dummy[2].setLocalData(new int(4)); + dummy[3].setLocalData(new int(3)); + tls1.setLocalData(new QString()); +} + +void tst_QThreadStorage::cleanup() +{ +} + +void tst_QThreadStorage::construct() +{ + QBENCHMARK { + QThreadStorage<int *> ts; + } +} + + +void tst_QThreadStorage::get() +{ + QThreadStorage<int *> ts; + ts.setLocalData(new int(45)); + + int count = 0; + QBENCHMARK { + int *i = ts.localData(); + count += *i; + } + ts.setLocalData(0); +} + +void tst_QThreadStorage::set() +{ + QThreadStorage<int *> ts; + + int count = 0; + QBENCHMARK { + ts.setLocalData(new int(count)); + count++; + } + ts.setLocalData(0); +} + + +QTEST_MAIN(tst_QThreadStorage) +#include "tst_qthreadstorage.moc" diff --git a/tests/benchmarks/corelib/thread/thread.pro b/tests/benchmarks/corelib/thread/thread.pro new file mode 100644 index 0000000..26570ba --- /dev/null +++ b/tests/benchmarks/corelib/thread/thread.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qthreadstorage diff --git a/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro b/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro new file mode 100644 index 0000000..c6f3fa6 --- /dev/null +++ b/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro @@ -0,0 +1,8 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_containers-associative +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/containers-associative/main.cpp b/tests/benchmarks/corelib/tools/containers-associative/main.cpp new file mode 100644 index 0000000..4c6dae4 --- /dev/null +++ b/tests/benchmarks/corelib/tools/containers-associative/main.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtGui> +#include <QString> + +#include <qtest.h> + +class tst_associative_containers : public QObject +{ + Q_OBJECT +private slots: + void insert_data(); + void insert(); + void lookup_data(); + void lookup(); +}; + +template <typename T> +void testInsert(int size) +{ + T container; + + QBENCHMARK { + for (int i = 0; i < size; ++i) + container.insert(i, i); + } +} + +void tst_associative_containers::insert_data() +{ + QTest::addColumn<bool>("useHash"); + QTest::addColumn<int>("size"); + + for (int size = 10; size < 20000; size += 100) { + + const QByteArray sizeString = QByteArray::number(size); + + QTest::newRow(("hash--" + sizeString).constData()) << true << size; + QTest::newRow(("map--" + sizeString).constData()) << false << size; + } +} + +void tst_associative_containers::insert() +{ + QFETCH(bool, useHash); + QFETCH(int, size); + + QHash<int, int> testHash; + QMap<int, int> testMap; + + if (useHash) { + testInsert<QHash<int, int> >(size); + } else { + testInsert<QMap<int, int> >(size); + } +} + +void tst_associative_containers::lookup_data() +{ +// setReportType(LineChartReport); +// setChartTitle("Time to call value(), with an increasing number of items in the container"); + + QTest::addColumn<bool>("useHash"); + QTest::addColumn<int>("size"); + + for (int size = 10; size < 20000; size += 100) { + + const QByteArray sizeString = QByteArray::number(size); + + QTest::newRow(("hash--" + sizeString).constData()) << true << size; + QTest::newRow(("map--" + sizeString).constData()) << false << size; + } +} + +template <typename T> +void testLookup(int size) +{ + T container; + + for (int i = 0; i < size; ++i) + container.insert(i, i); + + int val; + + QBENCHMARK { + for (int i = 0; i < size; ++i) + val = container.value(i); + + } +} + +void tst_associative_containers::lookup() +{ + QFETCH(bool, useHash); + QFETCH(int, size); + + if (useHash) { + testLookup<QHash<int, int> >(size); + } else { + testLookup<QMap<int, int> >(size); + } +} + +QTEST_MAIN(tst_associative_containers) +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro b/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro new file mode 100644 index 0000000..bf6db44 --- /dev/null +++ b/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro @@ -0,0 +1,8 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_containers-sequential +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/containers-sequential/main.cpp b/tests/benchmarks/corelib/tools/containers-sequential/main.cpp new file mode 100644 index 0000000..a6e405c --- /dev/null +++ b/tests/benchmarks/corelib/tools/containers-sequential/main.cpp @@ -0,0 +1,265 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +// This file contains benchmarks for comparing QVector against std::vector + +#include <QtCore> +#include <QVector> +#include <vector> + +#include <qtest.h> + +template <typename T> // T is the item type +class UseCases { +public: + virtual ~UseCases() {} + + // Use case: Insert \a size items into the vector. + virtual void insert(int size) = 0; + + // Use case: Lookup \a size items from the vector. + virtual void lookup(int size) = 0; +}; + +template <typename T> +T * f(T *ts) // dummy function to prevent code from being optimized away by the compiler +{ + return ts; +} + +// This subclass implements the use cases using QVector as efficiently as possible. +template <typename T> +class UseCases_QVector : public UseCases<T> +{ + void insert(int size) + { + QVector<T> v; + T t; + QBENCHMARK { + for (int i = 0; i < size; ++i) + v.append(t); + } + } + + void lookup(int size) + { + QVector<T> v; + + T t; + for (int i = 0; i < size; ++i) + v.append(t); + + T *ts = new T[size]; + QBENCHMARK { + for (int i = 0; i < size; ++i) + ts[i] = v.value(i); + } + f<T>(ts); + delete[] ts; + } +}; + +// This subclass implements the use cases using std::vector as efficiently as possible. +template <typename T> +class UseCases_stdvector : public UseCases<T> +{ + void insert(int size) + { + std::vector<T> v; + T t; + QBENCHMARK { + for (int i = 0; i < size; ++i) + v.push_back(t); + } + } + + void lookup(int size) + { + std::vector<T> v; + + T t; + for (int i = 0; i < size; ++i) + v.push_back(t); + + T *ts = new T[size]; + QBENCHMARK { + for (int i = 0; i < size; ++i) + ts[i] = v[i]; + } + f<T>(ts); + delete[] ts; + } +}; + +struct Large { // A "large" item type + int x[1000]; +}; + +// Symbian devices typically have limited memory +#ifdef Q_OS_SYMBIAN +# define LARGE_MAX_SIZE 2000 +#else +# define LARGE_MAX_SIZE 20000 +#endif + +class tst_vector_vs_std : public QObject +{ + Q_OBJECT +public: + tst_vector_vs_std() + { + useCases_QVector_int = new UseCases_QVector<int>; + useCases_stdvector_int = new UseCases_stdvector<int>; + + useCases_QVector_Large = new UseCases_QVector<Large>; + useCases_stdvector_Large = new UseCases_stdvector<Large>; + } + +private: + UseCases<int> *useCases_QVector_int; + UseCases<int> *useCases_stdvector_int; + UseCases<Large> *useCases_QVector_Large; + UseCases<Large> *useCases_stdvector_Large; + +private slots: + void insert_int_data(); + void insert_int(); + void insert_Large_data(); + void insert_Large(); + void lookup_int_data(); + void lookup_int(); + void lookup_Large_data(); + void lookup_Large(); +}; + +void tst_vector_vs_std::insert_int_data() +{ + QTest::addColumn<bool>("useStd"); + QTest::addColumn<int>("size"); + + for (int size = 10; size < 20000; size += 100) { + const QByteArray sizeString = QByteArray::number(size); + QTest::newRow(("std::vector-int--" + sizeString).constData()) << true << size; + QTest::newRow(("QVector-int--" + sizeString).constData()) << false << size; + } +} + +void tst_vector_vs_std::insert_int() +{ + QFETCH(bool, useStd); + QFETCH(int, size); + + if (useStd) + useCases_stdvector_int->insert(size); + else + useCases_QVector_int->insert(size); +} + +void tst_vector_vs_std::insert_Large_data() +{ + QTest::addColumn<bool>("useStd"); + QTest::addColumn<int>("size"); + + for (int size = 10; size < LARGE_MAX_SIZE; size += 100) { + const QByteArray sizeString = QByteArray::number(size); + QTest::newRow(("std::vector-Large--" + sizeString).constData()) << true << size; + QTest::newRow(("QVector-Large--" + sizeString).constData()) << false << size; + } +} + +void tst_vector_vs_std::insert_Large() +{ + QFETCH(bool, useStd); + QFETCH(int, size); + + if (useStd) + useCases_stdvector_Large->insert(size); + else + useCases_QVector_Large->insert(size); +} + +void tst_vector_vs_std::lookup_int_data() +{ + QTest::addColumn<bool>("useStd"); + QTest::addColumn<int>("size"); + + for (int size = 10; size < 20000; size += 100) { + const QByteArray sizeString = QByteArray::number(size); + QTest::newRow(("std::vector-int--" + sizeString).constData()) << true << size; + QTest::newRow(("QVector-int--" + sizeString).constData()) << false << size; + } +} + +void tst_vector_vs_std::lookup_int() +{ + QFETCH(bool, useStd); + QFETCH(int, size); + + if (useStd) + useCases_stdvector_int->lookup(size); + else + useCases_QVector_int->lookup(size); +} + +void tst_vector_vs_std::lookup_Large_data() +{ + QTest::addColumn<bool>("useStd"); + QTest::addColumn<int>("size"); + + for (int size = 10; size < LARGE_MAX_SIZE; size += 100) { + const QByteArray sizeString = QByteArray::number(size); + QTest::newRow(("std::vector-Large--" + sizeString).constData()) << true << size; + QTest::newRow(("QVector-Large--" + sizeString).constData()) << false << size; + } +} + +void tst_vector_vs_std::lookup_Large() +{ + QFETCH(bool, useStd); + QFETCH(int, size); + + if (useStd) + useCases_stdvector_Large->lookup(size); + else + useCases_QVector_Large->lookup(size); +} + +QTEST_MAIN(tst_vector_vs_std) +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qbytearray/main.cpp b/tests/benchmarks/corelib/tools/qbytearray/main.cpp new file mode 100644 index 0000000..22d4815 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qbytearray/main.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QDebug> +#include <QIODevice> +#include <QFile> +#include <QString> + +#include <qtest.h> + + +class tst_qbytearray : public QObject +{ + Q_OBJECT +private slots: + void append(); + void append_data(); +}; + + +void tst_qbytearray::append_data() +{ + QTest::addColumn<int>("size"); + QTest::newRow("1") << int(1); + QTest::newRow("10") << int(10); + QTest::newRow("100") << int(100); + QTest::newRow("1000") << int(1000); + QTest::newRow("10000") << int(10000); + QTest::newRow("100000") << int(100000); + QTest::newRow("1000000") << int(1000000); + QTest::newRow("10000000") << int(10000000); + QTest::newRow("100000000") << int(100000000); +} + +void tst_qbytearray::append() +{ + QFETCH(int, size); + +#ifdef Q_OS_SYMBIAN + if (size > 1000000) + QSKIP("Skipped due to limited memory in many Symbian devices.", SkipSingle); +#endif + + QByteArray ba; + QBENCHMARK { + QByteArray ba2(size, 'x'); + ba.append(ba2); + ba.clear(); + } +} + + +QTEST_MAIN(tst_qbytearray) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qbytearray/qbytearray.pro b/tests/benchmarks/corelib/tools/qbytearray/qbytearray.pro new file mode 100755 index 0000000..a0bf021 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qbytearray/qbytearray.pro @@ -0,0 +1,12 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qbytearray +DEPENDPATH += . +INCLUDEPATH += . + +QT -= gui + +CONFIG += release + +# Input +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/qrect/main.cpp b/tests/benchmarks/corelib/tools/qrect/main.cpp new file mode 100644 index 0000000..e293bfa --- /dev/null +++ b/tests/benchmarks/corelib/tools/qrect/main.cpp @@ -0,0 +1,329 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +// This file contains benchmarks for QRect/QRectF functions. + +#include <QDebug> +#include <qtest.h> + +class tst_qrect : public QObject +{ + Q_OBJECT +private slots: + // QRect functions: + void contains_point_data(); + void contains_point(); + void contains_rect_data(); + void contains_rect(); + void intersects_data(); + void intersects(); + void intersected_data(); + void intersected(); + void united_data(); + void united(); + + // QRectF functions: + void contains_point_f_data(); + void contains_point_f(); + void contains_rect_f_data(); + void contains_rect_f(); + void intersects_f_data(); + void intersects_f(); + void intersected_f_data(); + void intersected_f(); + void united_f_data(); + void united_f(); +}; + +struct RectRectCombination +{ + QString tag; + qreal x1, y1, w1, h1, x2, y2, w2, h2; + RectRectCombination( + const QString &tag, + const qreal x1, const qreal y1, const qreal w1, const qreal h1, + const qreal x2, const qreal y2, const qreal w2, const qreal h2) + : tag(tag), x1(x1), y1(y1), w1(w1), h1(h1), x2(x2), y2(y2), w2(w2), h2(h2) {} +}; + +static QList<RectRectCombination> createRectRectCombinations() +{ + QList<RectRectCombination> result; + result << RectRectCombination("null", 0, 0, 0, 0, 0, 0, 0, 0); + result << RectRectCombination("null1", 0, 0, 0, 0, 0, 0, 10, 10); + result << RectRectCombination("null2", 0, 0, 10, 10, 0, 0, 0, 0); + + result << RectRectCombination("miss", 0, 0, 10, 10, 11, 11, 10, 10); + result << RectRectCombination("intersect", 0, 0, 10, 10, 5, 5, 10, 10); + result << RectRectCombination("contain1", 0, 0, 10, 10, 1, 1, 8, 8); + result << RectRectCombination("contain2", 1, 1, 8, 8, 0, 0, 10, 10); + + result << RectRectCombination("miss_flip1", 9, 9, -10, -10, 11, 11, 10, 10); + result << RectRectCombination("intersect_flip1", 9, 9, -10, -10, 5, 5, 10, 10); + result << RectRectCombination("contain1_flip1", 9, 9, -10, -10, 1, 1, 8, 8); + result << RectRectCombination("contain2_flip1", 8, 8, -8, -8, 0, 0, 10, 10); + + result << RectRectCombination("miss_flip2", 0, 0, 10, 10, 20, 20, -10, -10); + result << RectRectCombination("intersect_flip2", 0, 0, 10, 10, 14, 14, -10, -10); + result << RectRectCombination("contain1_flip2", 0, 0, 10, 10, 8, 8, -8, -8); + result << RectRectCombination("contain2_flip2", 1, 1, 8, 8, 9, 9, -10, -10); + + return result; +} + +static void addRectRectData(bool includeProperArg = false) +{ + QTest::addColumn<QRectF>("rf1"); + QTest::addColumn<QRectF>("rf2"); + if (includeProperArg) + QTest::addColumn<bool>("proper"); + for (int i = 0; i < (includeProperArg ? 2 : 1); ++i) { + QList<RectRectCombination> combinations = createRectRectCombinations(); + foreach (RectRectCombination c, combinations) { + QTestData &testData = QTest::newRow(c.tag.toLatin1().data()); + QRectF r1(c.x1, c.y1, c.w1, c.h1); + QRectF r2(c.x2, c.y2, c.w2, c.h2); + testData << r1 << r2; + if (includeProperArg) + testData << (i == 0); + } + } +} + +struct RectPointCombination +{ + QString tag; + qreal x, y, w, h, px, py; + RectPointCombination( + const QString &tag, + const qreal x, const qreal y, const qreal w, const qreal h, const qreal px, const qreal py) + : tag(tag), x(x), y(y), w(w), h(h), px(px), py(py) {} +}; + +static QList<RectPointCombination> createRectPointCombinations() +{ + QList<RectPointCombination> result; + result << RectPointCombination("null", 0, 0, 0, 0, 0, 0); + + result << RectPointCombination("miss", 0, 0, 10, 10, -1, -1); + result << RectPointCombination("contain", 0, 0, 10, 10, 0, 0); + result << RectPointCombination("contain_proper", 0, 0, 10, 10, 1, 1); + + result << RectPointCombination("miss_flip", 9, 9, -10, -10, -1, -1); + result << RectPointCombination("contain_flip", 9, 9, -10, -10, 0, 0); + result << RectPointCombination("contain_flip_proper", 9, 9, -10, -10, 1, 1); + + return result; +} + +static void addRectPointData(bool includeProperArg = false) +{ + QTest::addColumn<QRectF>("rf"); + QTest::addColumn<QPointF>("pf"); + if (includeProperArg) + QTest::addColumn<bool>("proper"); + for (int i = 0; i < (includeProperArg ? 2 : 1); ++i) { + QList<RectPointCombination> combinations = createRectPointCombinations(); + foreach (RectPointCombination c, combinations) { + QTestData &testData = QTest::newRow(c.tag.toLatin1().data()); + QRectF r(c.x, c.y, c.w, c.h); + QPointF p(c.px, c.py); + testData << r << p; + if (includeProperArg) + testData << (i == 0); + } + } +} + +void tst_qrect::contains_point_data() +{ + addRectPointData(true); +} + +void tst_qrect::contains_point() +{ + QFETCH(QRectF, rf); + QFETCH(QPointF, pf); + QFETCH(bool, proper); + QRect r(rf.toRect()); + QPoint p(pf.toPoint()); + QBENCHMARK { + r.contains(p, proper); + } +} + +void tst_qrect::contains_rect_data() +{ + addRectRectData(true); +} + +void tst_qrect::contains_rect() +{ + QFETCH(QRectF, rf1); + QFETCH(QRectF, rf2); + QFETCH(bool, proper); + QRect r1(rf1.toRect()); + QRect r2(rf2.toRect()); + QBENCHMARK { + r1.contains(r2, proper); + } +} + +void tst_qrect::intersects_data() +{ + addRectRectData(); +} + +void tst_qrect::intersects() +{ + QFETCH(QRectF, rf1); + QFETCH(QRectF, rf2); + QRect r1(rf1.toRect()); + QRect r2(rf2.toRect()); + QBENCHMARK { + r1.intersects(r2); + } +} + +void tst_qrect::intersected_data() +{ + addRectRectData(); +} + +void tst_qrect::intersected() +{ + QFETCH(QRectF, rf1); + QFETCH(QRectF, rf2); + QRect r1(rf1.toRect()); + QRect r2(rf2.toRect()); + QBENCHMARK { + r1.intersected(r2); + } +} + +void tst_qrect::united_data() +{ + addRectRectData(); +} + +void tst_qrect::united() +{ + QFETCH(QRectF, rf1); + QFETCH(QRectF, rf2); + QRect r1(rf1.toRect()); + QRect r2(rf2.toRect()); + QBENCHMARK { + r1.united(r2); + } +} + +void tst_qrect::contains_point_f_data() +{ + addRectPointData(); +} + +void tst_qrect::contains_point_f() +{ + QFETCH(QRectF, rf); + QFETCH(QPointF, pf); + QBENCHMARK { + rf.contains(pf); + } +} + +void tst_qrect::contains_rect_f_data() +{ + addRectRectData(); +} + +void tst_qrect::contains_rect_f() +{ + QFETCH(QRectF, rf1); + QFETCH(QRectF, rf2); + QBENCHMARK { + rf1.contains(rf2); + } +} + +void tst_qrect::intersects_f_data() +{ + addRectRectData(); +} + +void tst_qrect::intersects_f() +{ + QFETCH(QRectF, rf1); + QFETCH(QRectF, rf2); + QBENCHMARK { + rf1.intersects(rf2); + } +} + +void tst_qrect::intersected_f_data() +{ + addRectRectData(); +} + +void tst_qrect::intersected_f() +{ + QFETCH(QRectF, rf1); + QFETCH(QRectF, rf2); + QBENCHMARK { + rf1.intersected(rf2); + } +} + +void tst_qrect::united_f_data() +{ + addRectRectData(); +} + +void tst_qrect::united_f() +{ + QFETCH(QRectF, rf1); + QFETCH(QRectF, rf2); + QBENCHMARK { + rf1.united(rf2); + } +} + +QTEST_MAIN(tst_qrect) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qrect/qrect.pro b/tests/benchmarks/corelib/tools/qrect/qrect.pro new file mode 100644 index 0000000..6e35119 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qrect/qrect.pro @@ -0,0 +1,12 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qrect +DEPENDPATH += . +INCLUDEPATH += . + +QT -= gui + +CONFIG += release + +# Input +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/qregexp/main.cpp b/tests/benchmarks/corelib/tools/qregexp/main.cpp new file mode 100644 index 0000000..ab9ed71 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qregexp/main.cpp @@ -0,0 +1,290 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QDebug> +#include <QRegExp> +#include <QString> + +#include <qtest.h> + + +class tst_qregexp : public QObject +{ + Q_OBJECT +private slots: + void escape_old(); + void escape_old_data() { escape_data(); } + void escape_new1(); + void escape_new1_data() { escape_data(); } + void escape_new2(); + void escape_new2_data() { escape_data(); } + void escape_new3(); + void escape_new3_data() { escape_data(); } + void escape_new4(); + void escape_new4_data() { escape_data(); } +private: + void escape_data(); +}; + + +static void verify(const QString "ed, const QString &expected) +{ + if (quoted != expected) + qDebug() << "ERROR:" << quoted << expected; +} + +void tst_qregexp::escape_data() +{ + QTest::addColumn<QString>("pattern"); + QTest::addColumn<QString>("expected"); + + QTest::newRow("escape 0") << "Hello world" << "Hello world"; + QTest::newRow("escape 1") << "(Hello world)" << "\\(Hello world\\)"; + { + QString s; + for (int i = 0; i < 10; ++i) + s += "(escape)"; + QTest::newRow("escape 10") << s << QRegExp::escape(s); + } + { + QString s; + for (int i = 0; i < 100; ++i) + s += "(escape)"; + QTest::newRow("escape 100") << s << QRegExp::escape(s); + } +} + +void tst_qregexp::escape_old() +{ + QFETCH(QString, pattern); + QFETCH(QString, expected); + + QBENCHMARK { + static const char meta[] = "$()*+.?[\\]^{|}"; + QString quoted = pattern; + int i = 0; + + while (i < quoted.length()) { + if (strchr(meta, quoted.at(i).toLatin1()) != 0) + quoted.insert(i++, QLatin1Char('\\')); + ++i; + } + + verify(quoted, expected); + } +} + +void tst_qregexp::escape_new1() +{ + QFETCH(QString, pattern); + QFETCH(QString, expected); + + QBENCHMARK { + QString quoted; + const int count = pattern.count(); + quoted.reserve(count * 2); + const QLatin1Char backslash('\\'); + for (int i = 0; i < count; i++) { + switch (pattern.at(i).toLatin1()) { + case '$': + case '(': + case ')': + case '*': + case '+': + case '.': + case '?': + case '[': + case '\\': + case ']': + case '^': + case '{': + case '|': + case '}': + quoted.append(backslash); + } + quoted.append(pattern.at(i)); + } + verify(quoted, expected); + } +} + +void tst_qregexp::escape_new2() +{ + QFETCH(QString, pattern); + QFETCH(QString, expected); + + QBENCHMARK { + int count = pattern.count(); + const QLatin1Char backslash('\\'); + QString quoted(count * 2, backslash); + const QChar *patternData = pattern.data(); + QChar *quotedData = quoted.data(); + int escaped = 0; + for ( ; --count >= 0; ++patternData) { + const QChar c = *patternData; + switch (c.unicode()) { + case '$': + case '(': + case ')': + case '*': + case '+': + case '.': + case '?': + case '[': + case '\\': + case ']': + case '^': + case '{': + case '|': + case '}': + ++escaped; + ++quotedData; + } + *quotedData = c; + ++quotedData; + } + quoted.resize(pattern.size() + escaped); + + verify(quoted, expected); + } +} + +void tst_qregexp::escape_new3() +{ + QFETCH(QString, pattern); + QFETCH(QString, expected); + + QBENCHMARK { + QString quoted; + const int count = pattern.count(); + quoted.reserve(count * 2); + const QLatin1Char backslash('\\'); + for (int i = 0; i < count; i++) { + switch (pattern.at(i).toLatin1()) { + case '$': + case '(': + case ')': + case '*': + case '+': + case '.': + case '?': + case '[': + case '\\': + case ']': + case '^': + case '{': + case '|': + case '}': + quoted += backslash; + } + quoted += pattern.at(i); + } + + verify(quoted, expected); + } +} + + +static inline bool needsEscaping(int c) +{ + switch (c) { + case '$': + case '(': + case ')': + case '*': + case '+': + case '.': + case '?': + case '[': + case '\\': + case ']': + case '^': + case '{': + case '|': + case '}': + return true; + } + return false; +} + +void tst_qregexp::escape_new4() +{ + QFETCH(QString, pattern); + QFETCH(QString, expected); + + QBENCHMARK { + const int n = pattern.size(); + const QChar *patternData = pattern.data(); + // try to prevent copy if no escape is needed + int i = 0; + for (int i = 0; i != n; ++i) { + const QChar c = patternData[i]; + if (needsEscaping(c.unicode())) + break; + } + if (i == n) { + verify(pattern, expected); + // no escaping needed, "return pattern" should be done here. + return; + } + const QLatin1Char backslash('\\'); + QString quoted(n * 2, backslash); + QChar *quotedData = quoted.data(); + for (int j = 0; j != i; ++j) + *quotedData++ = *patternData++; + int escaped = 0; + for (; i != n; ++i) { + const QChar c = *patternData; + if (needsEscaping(c.unicode())) { + ++escaped; + ++quotedData; + } + *quotedData = c; + ++quotedData; + ++patternData; + } + quoted.resize(n + escaped); + verify(quoted, expected); + // "return quoted" + } +} +QTEST_MAIN(tst_qregexp) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qregexp/qregexp.pro b/tests/benchmarks/corelib/tools/qregexp/qregexp.pro new file mode 100644 index 0000000..83d723c --- /dev/null +++ b/tests/benchmarks/corelib/tools/qregexp/qregexp.pro @@ -0,0 +1,12 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qregexp +DEPENDPATH += . +INCLUDEPATH += . + +QT -= gui + +CONFIG += release + +# Input +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/qstring/main.cpp b/tests/benchmarks/corelib/tools/qstring/main.cpp new file mode 100644 index 0000000..12826eb --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstring/main.cpp @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QStringList> +#include <QFile> +#include <qtest.h> + +#ifdef Q_OS_SYMBIAN +// In Symbian OS test data is located in applications private dir +// Application private dir is default serach path for files, so SRCDIR can be set to empty +#define SRCDIR "" +#endif + +class tst_QString: public QObject +{ + Q_OBJECT +private slots: + void equals() const; + void equals_data() const; + void fromUtf8() const; +}; + +void tst_QString::equals() const +{ + QFETCH(QString, a); + QFETCH(QString, b); + + QBENCHMARK { + a == b; + } +} + +void tst_QString::equals_data() const +{ + static const struct { + ushort data[80]; + int dummy; // just to ensure 4-byte alignment + } data = { + { + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, // 16 + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, // 32 + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, // 48 + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, // 64 + 64, 64, 64, 64, 96, 96, 96, 96, + 64, 64, 96, 96, 96, 96, 96, 96 // 80 + }, 0 + }; + const QChar *ptr = reinterpret_cast<const QChar *>(data.data); + + QTest::addColumn<QString>("a"); + QTest::addColumn<QString>("b"); + QString base = QString::fromRawData(ptr, 64); + + QTest::newRow("different-length") << base << QString::fromRawData(ptr, 4); + QTest::newRow("same-string") << base << base; + QTest::newRow("same-data") << base << QString::fromRawData(ptr, 64); + + // try to avoid crossing a cache line (that is, at ptr[64]) + QTest::newRow("aligned-aligned-4n") + << QString::fromRawData(ptr, 60) << QString::fromRawData(ptr + 2, 60); + QTest::newRow("aligned-unaligned-4n") + << QString::fromRawData(ptr, 60) << QString::fromRawData(ptr + 1, 60); + QTest::newRow("unaligned-unaligned-4n") + << QString::fromRawData(ptr + 1, 60) << QString::fromRawData(ptr + 3, 60); + + QTest::newRow("aligned-aligned-4n+1") + << QString::fromRawData(ptr, 61) << QString::fromRawData(ptr + 2, 61); + QTest::newRow("aligned-unaligned-4n+1") + << QString::fromRawData(ptr, 61) << QString::fromRawData(ptr + 1, 61); + QTest::newRow("unaligned-unaligned-4n+1") + << QString::fromRawData(ptr + 1, 61) << QString::fromRawData(ptr + 3, 61); + + QTest::newRow("aligned-aligned-4n-1") + << QString::fromRawData(ptr, 59) << QString::fromRawData(ptr + 2, 59); + QTest::newRow("aligned-unaligned-4n-1") + << QString::fromRawData(ptr, 59) << QString::fromRawData(ptr + 1, 59); + QTest::newRow("unaligned-unaligned-4n-1") + << QString::fromRawData(ptr + 1, 59) << QString::fromRawData(ptr + 3, 59); + + QTest::newRow("aligned-aligned-2n") + << QString::fromRawData(ptr, 58) << QString::fromRawData(ptr + 2, 58); + QTest::newRow("aligned-unaligned-2n") + << QString::fromRawData(ptr, 58) << QString::fromRawData(ptr + 1, 58); + QTest::newRow("unaligned-unaligned-2n") + << QString::fromRawData(ptr + 1, 58) << QString::fromRawData(ptr + 3, 58); +} + +void tst_QString::fromUtf8() const +{ + QFile file(SRCDIR "utf-8.txt"); + if (!file.open(QFile::ReadOnly)) { + qFatal("Cannot open input file"); + return; + } + QByteArray data = file.readAll(); + const char *d = data.constData(); + int size = data.size(); + + QBENCHMARK { + QString::fromUtf8(d, size); + } +} + +QTEST_MAIN(tst_QString) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qstring/qstring.pro b/tests/benchmarks/corelib/tools/qstring/qstring.pro new file mode 100644 index 0000000..2e7c86a --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstring/qstring.pro @@ -0,0 +1,16 @@ +load(qttest_p4) +TARGET = tst_qstring +QT -= gui +SOURCES += main.cpp + +wince*:{ + DEFINES += SRCDIR=\\\"\\\" +} else:symbian* { + addFiles.sources = utf-8.txt + addFiles.path = . + DEPLOYMENT += addFiles + TARGET.EPOCHEAPSIZE="0x100 0x1000000" +} else { + DEFINES += SRCDIR=\\\"$$PWD/\\\" +} + diff --git a/tests/benchmarks/corelib/tools/qstring/utf-8.txt b/tests/benchmarks/corelib/tools/qstring/utf-8.txt new file mode 100644 index 0000000..a8a58de --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstring/utf-8.txt @@ -0,0 +1,72 @@ +Språk: Norsk +Γλώσσα: Ελληνικά +Язык: Русский +언어 : 한국어 +言語: 日本語 +Langage : Français +Språk: Norsk +Γλώσσα: Ελληνικά +Язык: Русский +언어 : 한국어 +言語: 日本語 +Langage : Français +Språk: Norsk +Γλώσσα: Ελληνικά +Язык: Русский +언어 : 한국어 +言語: 日本語 +Langage : Français +Språk: Norsk +Γλώσσα: Ελληνικά +Язык: Русский +언어 : 한국어 +言語: 日本語 +Langage : Français +Språk: Norsk +Γλώσσα: Ελληνικά +Язык: Русский +언어 : 한국어 +言語: 日本語 +Langage : Français +Språk: Norsk +Γλώσσα: Ελληνικά +Язык: Русский +언어 : 한국어 +言語: 日本語 +Langage : Français +Språk: Norsk +Γλώσσα: Ελληνικά +Язык: Русский +언어 : 한국어 +言語: 日本語 +Langage : Français +Språk: Norsk +Γλώσσα: Ελληνικά +Язык: Русский +언어 : 한국어 +言語: 日本語 +Langage : Français +Språk: Norsk +Γλώσσα: Ελληνικά +Язык: Русский +언어 : 한국어 +言語: 日本語 +Langage : Français +Språk: Norsk +Γλώσσα: Ελληνικά +Язык: Русский +언어 : 한국어 +言語: 日本語 +Langage : Français +Språk: Norsk +Γλώσσα: Ελληνικά +Язык: Русский +언어 : 한국어 +言語: 日本語 +Langage : Français +Språk: Norsk +Γλώσσα: Ελληνικά +Язык: Русский +언어 : 한국어 +言語: 日本語 +Langage : Français diff --git a/tests/benchmarks/corelib/tools/qstringbuilder/main.cpp b/tests/benchmarks/corelib/tools/qstringbuilder/main.cpp new file mode 100644 index 0000000..9bd146f --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstringbuilder/main.cpp @@ -0,0 +1,464 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// Select one of the scenarios below +#define SCENARIO 1 + +#if SCENARIO == 1 +// this is the "no harm done" version. Only operator% is active, +// with NO_CAST * defined +#define P % +#undef QT_USE_FAST_OPERATOR_PLUS +#undef QT_USE_FAST_CONCATENATION +#define QT_NO_CAST_FROM_ASCII +#define QT_NO_CAST_TO_ASCII +#endif + + +#if SCENARIO == 2 +// this is the "full" version. Operator+ is replaced by a QStringBuilder +// based version +// with NO_CAST * defined +#define P + +#define QT_USE_FAST_OPERATOR_PLUS +#define QT_USE_FAST_CONCATENATION +#define QT_NO_CAST_FROM_ASCII +#define QT_NO_CAST_TO_ASCII +#endif + +#if SCENARIO == 3 +// this is the "no harm done" version. Only operator% is active, +// with NO_CAST * _not_ defined +#define P % +#undef QT_USE_FAST_OPERATOR_PLUS +#undef QT_USE_FAST_CONCATENATION +#undef QT_NO_CAST_FROM_ASCII +#undef QT_NO_CAST_TO_ASCII +#endif + +#if SCENARIO == 4 +// this is the "full" version. Operator+ is replaced by a QStringBuilder +// based version +// with NO_CAST * _not_ defined +#define P + +#define QT_USE_FAST_OPERATOR_PLUS +#define QT_USE_FAST_CONCATENATION +#undef QT_NO_CAST_FROM_ASCII +#undef QT_NO_CAST_TO_ASCII +#endif + + +#include <qbytearray.h> +#include <qdebug.h> +#include <qstring.h> +#include <qstringbuilder.h> + +#include <qtest.h> + +#include <string> + +#define COMPARE(a, b) QCOMPARE(a, b) +//#define COMPARE(a, b) + +#define SEP(s) qDebug() << "\n\n-------- " s " ---------"; + +#define LITERAL "some string literal" + +class tst_qstringbuilder : public QObject +{ + Q_OBJECT + +public: + tst_qstringbuilder() + : l1literal(LITERAL), + l1string(LITERAL), + ba(LITERAL), + string(l1string), + stdstring(LITERAL), + stringref(&string, 2, 10), + achar('c'), + r2(QLatin1String(LITERAL LITERAL)), + r3(QLatin1String(LITERAL LITERAL LITERAL)), + r4(QLatin1String(LITERAL LITERAL LITERAL LITERAL)), + r5(QLatin1String(LITERAL LITERAL LITERAL LITERAL LITERAL)) + {} + + +public: + enum { N = 10000 }; + + int run_traditional() + { + int s = 0; + for (int i = 0; i < N; ++i) { +#if 0 + s += QString(l1string + l1string).size(); + s += QString(l1string + l1string + l1string).size(); + s += QString(l1string + l1string + l1string + l1string).size(); + s += QString(l1string + l1string + l1string + l1string + l1string).size(); +#endif + s += QString(achar + l1string + achar).size(); + } + return s; + } + + int run_builder() + { + int s = 0; + for (int i = 0; i < N; ++i) { +#if 0 + s += QString(l1literal P l1literal).size(); + s += QString(l1literal P l1literal P l1literal).size(); + s += QString(l1literal P l1literal P l1literal P l1literal).size(); + s += QString(l1literal P l1literal P l1literal P l1literal P l1literal).size(); +#endif + s += QString(achar % l1literal % achar).size(); + } + return s; + } + +private slots: + + void separator_0() { + qDebug() << "\nIn each block the QStringBuilder based result appear first " + "(with a 'b_' prefix), QStringBased second ('q_' prefix), std::string " + "last ('s_' prefix)\n"; + } + + void separator_1() { SEP("literal + literal (builder first)"); } + + void b_2_l1literal() { + QBENCHMARK { r = l1literal P l1literal; } + COMPARE(r, r2); + } + #ifndef QT_NO_CAST_FROM_ASCII + void b_l1literal_LITERAL() { + QBENCHMARK { r = l1literal P LITERAL; } + COMPARE(r, r2); + } + #endif + void q_2_l1string() { + QBENCHMARK { r = l1string + l1string; } + COMPARE(r, r2); + } + + + void separator_2() { SEP("2 strings"); } + + void b_2_string() { + QBENCHMARK { r = string P string; } + COMPARE(r, r2); + } + void q_2_string() { + QBENCHMARK { r = string + string; } + COMPARE(r, r2); + } + void s_2_string() { + QBENCHMARK { stdr = stdstring + stdstring; } + COMPARE(stdr, stdstring + stdstring); + } + + + void separator_2c() { SEP("2 string refs"); } + + void b_2_stringref() { + QBENCHMARK { r = stringref % stringref; } + COMPARE(r, QString(stringref.toString() + stringref.toString())); + } + void q_2_stringref() { + QBENCHMARK { r = stringref.toString() + stringref.toString(); } + COMPARE(r, QString(stringref % stringref)); + } + + + void separator_2b() { SEP("3 strings"); } + + void b_3_string() { + QBENCHMARK { r = string P string P string; } + COMPARE(r, r3); + } + void q_3_string() { + QBENCHMARK { r = string + string + string; } + COMPARE(r, r3); + } + void s_3_string() { + QBENCHMARK { stdr = stdstring + stdstring + stdstring; } + COMPARE(stdr, stdstring + stdstring + stdstring); + } + + void separator_2e() { SEP("4 strings"); } + + void b_4_string() { + QBENCHMARK { r = string P string P string P string; } + COMPARE(r, r4); + } + void q_4_string() { + QBENCHMARK { r = string + string + string + string; } + COMPARE(r, r4); + } + void s_4_string() { + QBENCHMARK { stdr = stdstring + stdstring + stdstring + stdstring; } + COMPARE(stdr, stdstring + stdstring + stdstring + stdstring); + } + + + + void separator_2a() { SEP("string + literal (builder first)"); } + + void b_string_l1literal() { + QBENCHMARK { r = string % l1literal; } + COMPARE(r, r2); + } + #ifndef QT_NO_CAST_FROM_ASCII + void b_string_LITERAL() { + QBENCHMARK { r = string P LITERAL; } + COMPARE(r, r2); + } + void b_LITERAL_string() { + QBENCHMARK { r = LITERAL P string; } + COMPARE(r, r2); + } + #endif + void b_string_l1string() { + QBENCHMARK { r = string P l1string; } + COMPARE(r, r2); + } + void q_string_l1literal() { + QBENCHMARK { r = string + l1string; } + COMPARE(r, r2); + } + void q_string_l1string() { + QBENCHMARK { r = string + l1string; } + COMPARE(r, r2); + } + void s_LITERAL_string() { + QBENCHMARK { stdr = LITERAL + stdstring; } + COMPARE(stdr, stdstring + stdstring); + } + + + void separator_3() { SEP("3 literals"); } + + void b_3_l1literal() { + QBENCHMARK { r = l1literal P l1literal P l1literal; } + COMPARE(r, r3); + } + void q_3_l1string() { + QBENCHMARK { r = l1string + l1string + l1string; } + COMPARE(r, r3); + } + void s_3_l1string() { + QBENCHMARK { stdr = stdstring + LITERAL + LITERAL; } + COMPARE(stdr, stdstring + stdstring + stdstring); + } + + + void separator_4() { SEP("4 literals"); } + + void b_4_l1literal() { + QBENCHMARK { r = l1literal P l1literal P l1literal P l1literal; } + COMPARE(r, r4); + } + void q_4_l1string() { + QBENCHMARK { r = l1string + l1string + l1string + l1string; } + COMPARE(r, r4); + } + + + void separator_5() { SEP("5 literals"); } + + void b_5_l1literal() { + QBENCHMARK { r = l1literal P l1literal P l1literal P l1literal P l1literal; } + COMPARE(r, r5); + } + + void q_5_l1string() { + QBENCHMARK { r = l1string + l1string + l1string + l1string + l1string; } + COMPARE(r, r5); + } + + + void separator_6() { SEP("4 chars"); } + + void b_string_4_char() { + QBENCHMARK { r = string + achar + achar + achar + achar; } + COMPARE(r, QString(string P achar P achar P achar P achar)); + } + + void q_string_4_char() { + QBENCHMARK { r = string + achar + achar + achar + achar; } + COMPARE(r, QString(string P achar P achar P achar P achar)); + } + + void s_string_4_char() { + QBENCHMARK { stdr = stdstring + 'c' + 'c' + 'c' + 'c'; } + COMPARE(stdr, stdstring + 'c' + 'c' + 'c' + 'c'); + } + + + void separator_7() { SEP("char + string + char"); } + + void b_char_string_char() { + QBENCHMARK { r = achar + string + achar; } + COMPARE(r, QString(achar P string P achar)); + } + + void q_char_string_char() { + QBENCHMARK { r = achar + string + achar; } + COMPARE(r, QString(achar P string P achar)); + } + + void s_char_string_char() { + QBENCHMARK { stdr = 'c' + stdstring + 'c'; } + COMPARE(stdr, 'c' + stdstring + 'c'); + } + + + void separator_8() { SEP("string.arg"); } + + void b_string_arg() { + const QString pattern = l1string + QString::fromLatin1("%1") + l1string; + QBENCHMARK { r = l1literal P string P l1literal; } + COMPARE(r, r3); + } + + void q_string_arg() { + const QString pattern = l1string + QLatin1String("%1") + l1string; + QBENCHMARK { r = pattern.arg(string); } + COMPARE(r, r3); + } + + void q_bytearray_arg() { + QByteArray result; + QBENCHMARK { result = ba + ba + ba; } + } + + + void separator_9() { SEP("QString::reserve()"); } + + void b_reserve() { + QBENCHMARK { + r.clear(); + r = string P string P string P string; + } + COMPARE(r, r4); + } + void b_reserve_lit() { + QBENCHMARK { + r.clear(); + r = string P l1literal P string P string; + } + COMPARE(r, r4); + } + void s_reserve() { + QBENCHMARK { + r.clear(); + r.reserve(string.size() + string.size() + string.size() + string.size()); + r += string; + r += string; + r += string; + r += string; + } + COMPARE(r, r4); + } + void s_reserve_lit() { + QBENCHMARK { + r.clear(); + //r.reserve(string.size() + qstrlen(l1string.latin1()) + // + string.size() + string.size()); + r.reserve(1024); + r += string; + r += l1string; + r += string; + r += string; + } + COMPARE(r, r4); + } + +private: + const QLatin1Literal l1literal; + const QLatin1String l1string; + const QByteArray ba; + const QString string; + const std::string stdstring; + const QStringRef stringref; + const QLatin1Char achar; + const QString r2, r3, r4, r5; + + // short cuts for results + QString r; + std::string stdr; +}; + + +//void operator%(QString, int) {} + +int main(int argc, char *argv[]) +{ + //qDebug() << (QString("xx") * QLatin1String("y")).toString(); + //42 % 3; // Sanity test, should always work. + //QString("x") % 2; // Sanity test, should only compile when the + // operator%(QString, int) is visible. + + if (argc == 2 && (QLatin1String(argv[1]) == QLatin1String("--run-builder") + || QLatin1String(argv[1]) == QLatin1String("-b"))) { + tst_qstringbuilder test; + return test.run_builder(); + } + + if (argc == 2 && (QLatin1String(argv[1]) == QLatin1String("--run-traditional") + || QLatin1String(argv[1]) == QLatin1String("-t"))) { + tst_qstringbuilder test; + return test.run_traditional(); + } + + if (argc == 1) { + QCoreApplication app(argc, argv); + QStringList args = app.arguments(); + tst_qstringbuilder test; + return QTest::qExec(&test, argc, argv); + } + + qDebug() << "Usage: " << argv[0] << " [--run-builder|-r|--run-traditional|-t]"; +} + + +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qstringbuilder/qstringbuilder.pro b/tests/benchmarks/corelib/tools/qstringbuilder/qstringbuilder.pro new file mode 100644 index 0000000..79171b4 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstringbuilder/qstringbuilder.pro @@ -0,0 +1,12 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qstringbuilder + +QMAKE_CXXFLAGS += -g +QMAKE_CFLAGS += -g + +QT -= gui + +CONFIG += release + +SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/qstringlist/.gitignore b/tests/benchmarks/corelib/tools/qstringlist/.gitignore new file mode 100644 index 0000000..3e0cdc9 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstringlist/.gitignore @@ -0,0 +1 @@ +tst_qstringlist diff --git a/tests/benchmarks/corelib/tools/qstringlist/main.cpp b/tests/benchmarks/corelib/tools/qstringlist/main.cpp new file mode 100644 index 0000000..1717b88 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstringlist/main.cpp @@ -0,0 +1,214 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QStringList> +#include <QtTest> + +#include <sstream> +#include <string> +#include <vector> + +class tst_QStringList: public QObject +{ + Q_OBJECT + +private slots: + void join() const; + void join_data() const; + + void split_qlist_qbytearray() const; + void split_qlist_qbytearray_data() const { return split_data(); } + + void split_data() const; + void split_qlist_qstring() const; + void split_qlist_qstring_data() const { return split_data(); } + + void split_stdvector_stdstring() const; + void split_stdvector_stdstring_data() const { return split_data(); } + + void split_stdvector_stdwstring() const; + void split_stdvector_stdwstring_data() const { return split_data(); } + + void split_stdlist_stdstring() const; + void split_stdlist_stdstring_data() const { return split_data(); } + +private: + static QStringList populateList(const int count, const QString &unit); + static QString populateString(const int count, const QString &unit); +}; + +QStringList tst_QStringList::populateList(const int count, const QString &unit) +{ + QStringList retval; + + for (int i = 0; i < count; ++i) + retval.append(unit); + + return retval; +} + +QString tst_QStringList::populateString(const int count, const QString &unit) +{ + QString retval; + + for (int i = 0; i < count; ++i) { + retval.append(unit); + retval.append(QLatin1Char(':')); + } + + return retval; +} + +void tst_QStringList::join() const +{ + QFETCH(QStringList, input); + QFETCH(QString, separator); + + QBENCHMARK { + input.join(separator); + } +} + +void tst_QStringList::join_data() const +{ + QTest::addColumn<QStringList>("input"); + QTest::addColumn<QString>("separator"); + + QTest::newRow("") + << populateList(100, QLatin1String("unit")) + << QString(); + + QTest::newRow("") + << populateList(1000, QLatin1String("unit")) + << QString(); + + QTest::newRow("") + << populateList(10000, QLatin1String("unit")) + << QString(); + + QTest::newRow("") + << populateList(100000, QLatin1String("unit")) + << QString(); +} + +void tst_QStringList::split_data() const +{ + QTest::addColumn<QString>("input"); + QString unit = QLatin1String("unit") + QString(100, QLatin1Char('s')); + //QTest::newRow("") << populateString(10, unit); + QTest::newRow("") << populateString(100, unit); + //QTest::newRow("") << populateString(100, unit); + //QTest::newRow("") << populateString(1000, unit); + //QTest::newRow("") << populateString(10000, unit); +} + +void tst_QStringList::split_qlist_qbytearray() const +{ + QFETCH(QString, input); + const char splitChar = ':'; + QByteArray ba = input.toLatin1(); + + QBENCHMARK { + ba.split(splitChar); + } +} + +void tst_QStringList::split_qlist_qstring() const +{ + QFETCH(QString, input); + const QChar splitChar = ':'; + + QBENCHMARK { + input.split(splitChar); + } +} + +void tst_QStringList::split_stdvector_stdstring() const +{ + QFETCH(QString, input); + const char split_char = ':'; + std::string stdinput = input.toStdString(); + + QBENCHMARK { + std::istringstream split(stdinput); + std::vector<std::string> token; + for (std::string each; + std::getline(split, each, split_char); + token.push_back(each)) + ; + } +} + +void tst_QStringList::split_stdvector_stdwstring() const +{ + QFETCH(QString, input); + const wchar_t split_char = ':'; + std::wstring stdinput = input.toStdWString(); + + QBENCHMARK { + std::wistringstream split(stdinput); + std::vector<std::wstring> token; + for (std::wstring each; + std::getline(split, each, split_char); + token.push_back(each)) + ; + } +} + +void tst_QStringList::split_stdlist_stdstring() const +{ + QFETCH(QString, input); + const char split_char = ':'; + std::string stdinput = input.toStdString(); + + QBENCHMARK { + std::istringstream split(stdinput); + std::list<std::string> token; + for (std::string each; + std::getline(split, each, split_char); + token.push_back(each)) + ; + } +} + +QTEST_MAIN(tst_QStringList) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qstringlist/qstringlist.pro b/tests/benchmarks/corelib/tools/qstringlist/qstringlist.pro new file mode 100644 index 0000000..5c64b34 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstringlist/qstringlist.pro @@ -0,0 +1,8 @@ +load(qttest_p4) +TARGET = tst_qstringlist +CONFIG -= debug +CONFIG += release +QT -= gui +SOURCES += main.cpp + +symbian: LIBS += -llibpthread diff --git a/tests/benchmarks/corelib/tools/tools.pro b/tests/benchmarks/corelib/tools/tools.pro new file mode 100644 index 0000000..12c23fc --- /dev/null +++ b/tests/benchmarks/corelib/tools/tools.pro @@ -0,0 +1,10 @@ +TEMPLATE = subdirs +SUBDIRS = \ + containers-associative \ + containers-sequential \ + qbytearray \ + qrect \ + qregexp \ + qstring \ + qstringbuilder \ + qstringlist |