mirror of
https://bitbucket.org/smil3y/katie.git
synced 2025-02-23 18:32:55 +00:00
add benchmarks from Qt4, some of which not yet ported to CMake build system
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
9cae2e9e5d
commit
7e2cedaf54
589 changed files with 166644 additions and 0 deletions
1
tests/auto/qsqldatabase/.gitignore
vendored
Normal file
1
tests/auto/qsqldatabase/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
tst_qsqldatabase
|
10
tests/auto/qsqldatabase/qsqldatabase.pro
Normal file
10
tests/auto/qsqldatabase/qsqldatabase.pro
Normal file
|
@ -0,0 +1,10 @@
|
|||
CONFIG += testcase
|
||||
TARGET = tst_qsqldatabase
|
||||
SOURCES += tst_qsqldatabase.cpp
|
||||
|
||||
QT += sql testlib
|
||||
|
||||
win32: {
|
||||
!wince*: LIBS += -lws2_32
|
||||
else: LIBS += -lws2
|
||||
}
|
BIN
tests/auto/qsqldatabase/testdata/qtest.mdb
vendored
Normal file
BIN
tests/auto/qsqldatabase/testdata/qtest.mdb
vendored
Normal file
Binary file not shown.
600
tests/auto/qsqldatabase/tst_databases.h
Normal file
600
tests/auto/qsqldatabase/tst_databases.h
Normal file
|
@ -0,0 +1,600 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
/* possible connection parameters */
|
||||
|
||||
#ifndef TST_DATABASES_H
|
||||
#define TST_DATABASES_H
|
||||
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlDriver>
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
#include <QRegExp>
|
||||
#include <QDir>
|
||||
#include <QVariant>
|
||||
#include <QDebug>
|
||||
#include <QSqlTableModel>
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#if defined (Q_OS_WIN) || defined (Q_OS_WIN32)
|
||||
# include <qt_windows.h>
|
||||
# if defined (Q_OS_WINCE)
|
||||
# include <winsock2.h>
|
||||
# endif
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define CHECK_DATABASE( db ) \
|
||||
if ( !db.isValid() ) { qFatal( "db is Invalid" ); }
|
||||
|
||||
#define QVERIFY_SQL(q, stmt) QVERIFY2((q).stmt, tst_Databases::printError((q).lastError(), db))
|
||||
#define QFAIL_SQL(q, stmt) QVERIFY2(!(q).stmt, tst_Databases::printError((q).lastError(), db))
|
||||
|
||||
#define DBMS_SPECIFIC(db, driver) \
|
||||
if (!db.driverName().startsWith(driver)) { QSKIP(driver " specific test", SkipSingle); return; }
|
||||
|
||||
// ### use QSystem::hostName if it is integrated in qtest/main
|
||||
static QString qGetHostName()
|
||||
{
|
||||
static QString hostname;
|
||||
|
||||
if ( !hostname.isEmpty() )
|
||||
return hostname;
|
||||
|
||||
char hn[257];
|
||||
|
||||
if ( gethostname( hn, 255 ) == 0 ) {
|
||||
hn[256] = '\0';
|
||||
hostname = QString::fromLatin1( hn );
|
||||
hostname.replace( QLatin1Char( '.' ), QLatin1Char( '_' ) );
|
||||
hostname.replace( QLatin1Char( '-' ), QLatin1Char( '_' ) );
|
||||
}
|
||||
|
||||
return hostname;
|
||||
}
|
||||
|
||||
// to prevent nameclashes on our database server, each machine
|
||||
// will use its own set of table names. Call this function to get
|
||||
// "tablename_hostname"
|
||||
inline static QString qTableName( const QString& prefix, const char *sourceFileName )
|
||||
{
|
||||
return QLatin1String("dbtst")+QString::number(qHash(QLatin1String(sourceFileName) + "_" + qGetHostName().replace( "-", "_" )), 16)+"_"+prefix;
|
||||
}
|
||||
|
||||
inline static QString qTableName( const QString& prefix, QSqlDriver* driver )
|
||||
{
|
||||
return driver->escapeIdentifier( prefix + "_" + qGetHostName(), QSqlDriver::TableName );
|
||||
}
|
||||
|
||||
inline static bool testWhiteSpaceNames( const QString &name )
|
||||
{
|
||||
/* return name.startsWith( "QPSQL" )
|
||||
|| name.startsWith( "QODBC" )
|
||||
|| name.startsWith( "QSQLITE" )
|
||||
|| name.startsWith( "QMYSQL" );*/
|
||||
return name != QLatin1String("QSQLITE2");
|
||||
}
|
||||
|
||||
inline static QString toHex( const QString& binary )
|
||||
{
|
||||
QString str;
|
||||
static char const hexchars[] = "0123456789ABCDEF";
|
||||
|
||||
for ( int i = 0; i < binary.size(); i++ ) {
|
||||
ushort code = binary.at(i).unicode();
|
||||
str += (QChar)(hexchars[ (code >> 12) & 0x0F ]);
|
||||
str += (QChar)(hexchars[ (code >> 8) & 0x0F ]);
|
||||
str += (QChar)(hexchars[ (code >> 4) & 0x0F ]);
|
||||
str += (QChar)(hexchars[ code & 0x0F ]);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
class tst_Databases
|
||||
{
|
||||
|
||||
public:
|
||||
tst_Databases(): counter( 0 ), m_sqLitePrefix(QDir::tempPath())
|
||||
{
|
||||
if (!m_sqLitePrefix.endsWith(QLatin1Char('/')))
|
||||
m_sqLitePrefix += QLatin1Char('/');
|
||||
m_sqLitePrefix += QLatin1String("foo");
|
||||
m_sqLitePrefix += QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch() % quint64(1000));
|
||||
}
|
||||
|
||||
~tst_Databases()
|
||||
{
|
||||
close();
|
||||
for (int i = m_sqLiteFiles.size() - 1; i >= 0; --i) {
|
||||
QFile sqLiteFile(m_sqLiteFiles.at(i));
|
||||
if (sqLiteFile.exists() && !sqLiteFile.remove()) {
|
||||
qWarning() << "Cannot remove " << QDir::toNativeSeparators(sqLiteFile.fileName())
|
||||
<< ':' << sqLiteFile.errorString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns a testtable consisting of the names of all database connections if
|
||||
// driverPrefix is empty, otherwise only those that start with driverPrefix.
|
||||
int fillTestTable( const QString& driverPrefix = QString() ) const
|
||||
{
|
||||
QTest::addColumn<QString>( "dbName" );
|
||||
int count = 0;
|
||||
|
||||
for ( int i = 0; i < dbNames.count(); ++i ) {
|
||||
QSqlDatabase db = QSqlDatabase::database( dbNames.at( i ) );
|
||||
|
||||
if ( !db.isValid() )
|
||||
continue;
|
||||
|
||||
if ( driverPrefix.isEmpty() || db.driverName().startsWith( driverPrefix ) ) {
|
||||
QTest::newRow( dbNames.at( i ).toLatin1() ) << dbNames.at( i );
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int fillTestTableWithStrategies( const QString& driverPrefix = QString() ) const
|
||||
{
|
||||
QTest::addColumn<QString>( "dbName" );
|
||||
QTest::addColumn<int>("submitpolicy_i");
|
||||
int count = 0;
|
||||
|
||||
for ( int i = 0; i < dbNames.count(); ++i ) {
|
||||
QSqlDatabase db = QSqlDatabase::database( dbNames.at( i ) );
|
||||
|
||||
if ( !db.isValid() )
|
||||
continue;
|
||||
|
||||
if ( driverPrefix.isEmpty() || db.driverName().startsWith( driverPrefix ) ) {
|
||||
QTest::newRow( QString("%1 [field]").arg(dbNames.at( i )).toLatin1() ) << dbNames.at( i ) << (int)QSqlTableModel::OnFieldChange;
|
||||
QTest::newRow( QString("%1 [row]").arg(dbNames.at( i )).toLatin1() ) << dbNames.at( i ) << (int)QSqlTableModel::OnRowChange;
|
||||
QTest::newRow( QString("%1 [manual]").arg(dbNames.at( i )).toLatin1() ) << dbNames.at( i ) << (int)QSqlTableModel::OnManualSubmit;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void addDb( const QString& driver, const QString& dbName,
|
||||
const QString& user = QString(), const QString& passwd = QString(),
|
||||
const QString& host = QString(), int port = -1, const QString params = QString() )
|
||||
{
|
||||
QSqlDatabase db;
|
||||
|
||||
if ( !QSqlDatabase::drivers().contains( driver ) ) {
|
||||
qWarning() << "Driver" << driver << "is not installed";
|
||||
return;
|
||||
}
|
||||
|
||||
// construct a stupid unique name
|
||||
QString cName = QString::number( counter++ ) + "_" + driver + "@";
|
||||
|
||||
cName += host.isEmpty() ? dbName : host;
|
||||
|
||||
if ( port > 0 )
|
||||
cName += ":" + QString::number( port );
|
||||
|
||||
db = QSqlDatabase::addDatabase( driver, cName );
|
||||
|
||||
if ( !db.isValid() ) {
|
||||
qWarning( "Could not create database object" );
|
||||
return;
|
||||
}
|
||||
|
||||
db.setDatabaseName( dbName );
|
||||
|
||||
db.setUserName( user );
|
||||
db.setPassword( passwd );
|
||||
db.setHostName( host );
|
||||
db.setPort( port );
|
||||
db.setConnectOptions( params );
|
||||
dbNames.append( cName );
|
||||
}
|
||||
|
||||
void addDbs()
|
||||
{
|
||||
// addDb( "QOCI8", "//horsehead.nokia.troll.no:1521/pony.troll.no", "scott", "tiger" ); // Oracle 9i on horsehead
|
||||
// addDb( "QOCI8", "//horsehead.nokia.troll.no:1521/ustest.troll.no", "scott", "tiger", "" ); // Oracle 9i on horsehead
|
||||
// addDb( "QOCI8", "//iceblink.nokia.troll.no:1521/ice.troll.no", "scott", "tiger", "" ); // Oracle 8 on iceblink (not currently working)
|
||||
// addDb( "QOCI", "//silence.nokia.troll.no:1521/testdb", "scott", "tiger" ); // Oracle 10g on silence
|
||||
// addDb( "QOCI", "//bq-oracle10g.apac.nokia.com:1521/XE", "scott", "tiger" ); // Oracle 10gexpress
|
||||
|
||||
// This requires a local ODBC data source to be configured( pointing to a MySql database )
|
||||
// addDb( "QODBC", "mysqlodbc", "troll", "trond" );
|
||||
// addDb( "QODBC", "SqlServer", "troll", "trond" );
|
||||
// addDb( "QTDS7", "testdb", "troll", "trondk", "horsehead" );
|
||||
// addDb( "QODBC", "silencetestdb", "troll", "trond", "silence" );
|
||||
// addDb( "QODBC", "horseheadtestdb", "troll", "trondk", "horsehead" );
|
||||
|
||||
// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.nokia.troll.no" );
|
||||
// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 3307 );
|
||||
// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 3308, "CLIENT_COMPRESS=1;CLIENT_SSL=1" ); // MySQL 4.1.1
|
||||
// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 3309, "CLIENT_COMPRESS=1;CLIENT_SSL=1" ); // MySQL 5.0.18 Linux
|
||||
// addDb( "QMYSQL3", "testdb", "troll", "trond", "silence.nokia.troll.no" ); // MySQL 5.1.36 Windows
|
||||
|
||||
// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql41.apac.nokia.com" ); // MySQL 4.1.22-2.el4 linux
|
||||
// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql50.apac.nokia.com" ); // MySQL 5.0.45-7.el5 linux
|
||||
// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql51.apac.nokia.com" ); // MySQL 5.1.36-6.7.2.i586 linux
|
||||
|
||||
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no" ); // V7.2 NOT SUPPORTED!
|
||||
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 5434 ); // V7.2 NOT SUPPORTED! Multi-byte
|
||||
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 5435 ); // V7.3
|
||||
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 5436 ); // V7.4
|
||||
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 5437 ); // V8.0.3
|
||||
// addDb( "QPSQL7", "testdb", "troll", "trond", "silence.nokia.troll.no" ); // V8.2.1, UTF-8
|
||||
|
||||
// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-postgres74.apac.nokia.com" ); // Version 7.4.19-1.el4_6.1
|
||||
// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql81.apac.nokia.com" ); // Version 8.1.11-1.el5_1.1
|
||||
// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql84.apac.nokia.com" ); // Version 8.4.1-2.1.i586
|
||||
// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql90.apac.nokia.com" ); // Version 9.0.0
|
||||
|
||||
|
||||
// addDb( "QDB2", "testdb", "troll", "trond", "silence.nokia.troll.no" ); // DB2 v9.1 on silence
|
||||
// addDb( "QDB2", "testdb", "testuser", "Ee4Gabf6_", "bq-db2-972.apac.nokia.com" ); // DB2
|
||||
|
||||
// yes - interbase really wants the physical path on the host machine.
|
||||
// addDb( "QIBASE", "/opt/interbase/qttest.gdb", "SYSDBA", "masterkey", "horsehead.nokia.troll.no" );
|
||||
// addDb( "QIBASE", "silence.troll.no:c:\\ibase\\testdb", "SYSDBA", "masterkey", "" ); // InterBase 7.5 on silence
|
||||
// addDb( "QIBASE", "silence.troll.no:c:\\ibase\\testdb_ascii", "SYSDBA", "masterkey", "" ); // InterBase 7.5 on silence
|
||||
// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "firebird1-nokia.trolltech.com.au" ); // Firebird 1.5.5
|
||||
// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "firebird2-nokia.trolltech.com.au" ); // Firebird 2.1.1
|
||||
|
||||
// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "bq-firebird1.apac.nokia.com" ); // Firebird 1.5.5
|
||||
// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "bq-firebird2.apac.nokia.com" ); // Firebird 2.1.1
|
||||
|
||||
// use in-memory database to prevent local files
|
||||
// addDb("QSQLITE", ":memory:");
|
||||
addDb( "QSQLITE", QDir::toNativeSeparators(sqLiteFileName()));
|
||||
// addDb( "QSQLITE2", QDir::toNativeSeparators(QDir::tempPath()+"/foo2.db") );
|
||||
// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=iceblink.nokia.troll.no\\ICEBLINK", "troll", "trond", "" );
|
||||
// addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.nokia.troll.no\\SQLEXPRESS", "troll", "trond", "" );
|
||||
|
||||
// addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=bq-mysql50.apac.nokia.com;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
|
||||
// addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=bq-mysql51.apac.nokia.com;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
|
||||
// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk", "troll", "trondk", "" );
|
||||
// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.nokia.troll.no;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond", "troll", "trond", "" );
|
||||
// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" );
|
||||
// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" );
|
||||
// addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2003" );
|
||||
// addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2008" );
|
||||
// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" );
|
||||
// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" );
|
||||
// addDb( "QODBC", "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=c:\\dbs\\access\\testdb.mdb", "", "", "" );
|
||||
// addDb( "QODBC", "DRIVER={Postgresql};SERVER=bq-pgsql84.apac.nokia.com;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
|
||||
}
|
||||
|
||||
void open()
|
||||
{
|
||||
addDbs();
|
||||
|
||||
QStringList::Iterator it = dbNames.begin();
|
||||
|
||||
while ( it != dbNames.end() ) {
|
||||
QSqlDatabase db = QSqlDatabase::database(( *it ), false );
|
||||
qDebug() << "Opening:" << (*it);
|
||||
|
||||
if ( db.isValid() && !db.isOpen() ) {
|
||||
if ( !db.open() ) {
|
||||
qWarning( "tst_Databases: Unable to open %s on %s:\n%s", qPrintable( db.driverName() ), qPrintable( *it ), qPrintable( db.lastError().databaseText() ) );
|
||||
// well... opening failed, so we just ignore the server, maybe it is not running
|
||||
it = dbNames.erase( it );
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
for ( QStringList::Iterator it = dbNames.begin(); it != dbNames.end(); ++it ) {
|
||||
{
|
||||
QSqlDatabase db = QSqlDatabase::database(( *it ), false );
|
||||
|
||||
if ( db.isValid() && db.isOpen() )
|
||||
db.close();
|
||||
}
|
||||
|
||||
QSqlDatabase::removeDatabase(( *it ) );
|
||||
}
|
||||
|
||||
dbNames.clear();
|
||||
}
|
||||
|
||||
// for debugging only: outputs the connection as string
|
||||
static QString dbToString( const QSqlDatabase db )
|
||||
{
|
||||
QString res = db.driverName() + "@";
|
||||
|
||||
if ( db.driverName().startsWith( "QODBC" ) || db.driverName().startsWith( "QOCI" ) ) {
|
||||
res += db.databaseName();
|
||||
} else {
|
||||
res += db.hostName();
|
||||
}
|
||||
|
||||
if ( db.port() > 0 ) {
|
||||
res += ":" + QString::number( db.port() );
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// drop a table only if it exists to prevent warnings
|
||||
static void safeDropTables( QSqlDatabase db, const QStringList& tableNames )
|
||||
{
|
||||
bool wasDropped;
|
||||
QSqlQuery q( db );
|
||||
QStringList dbtables=db.tables();
|
||||
|
||||
foreach(const QString &tableName, tableNames)
|
||||
{
|
||||
wasDropped = true;
|
||||
QString table=tableName;
|
||||
if ( db.driver()->isIdentifierEscaped(table, QSqlDriver::TableName))
|
||||
table = db.driver()->stripDelimiters(table, QSqlDriver::TableName);
|
||||
|
||||
if ( dbtables.contains( table, Qt::CaseInsensitive ) ) {
|
||||
foreach(const QString &table2, dbtables.filter(table, Qt::CaseInsensitive)) {
|
||||
if(table2.compare(table.section('.', -1, -1), Qt::CaseInsensitive) == 0) {
|
||||
table=db.driver()->escapeIdentifier(table2, QSqlDriver::TableName);
|
||||
if(isPostgreSQL(db))
|
||||
wasDropped = q.exec( "drop table " + table + " cascade");
|
||||
else
|
||||
wasDropped = q.exec( "drop table " + table);
|
||||
dbtables.removeAll(table2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !wasDropped ) {
|
||||
qWarning() << dbToString(db) << "unable to drop table" << tableName << ':' << q.lastError();
|
||||
// qWarning() << "last query:" << q.lastQuery();
|
||||
// qWarning() << "dbtables:" << dbtables;
|
||||
// qWarning() << "db.tables():" << db.tables();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void safeDropTable( QSqlDatabase db, const QString& tableName )
|
||||
{
|
||||
safeDropTables(db, QStringList() << tableName);
|
||||
}
|
||||
|
||||
static void safeDropViews( QSqlDatabase db, const QStringList &viewNames )
|
||||
{
|
||||
if ( isMSAccess( db ) ) // Access is sooo stupid.
|
||||
safeDropTables( db, viewNames );
|
||||
|
||||
bool wasDropped;
|
||||
QSqlQuery q( db );
|
||||
QStringList dbtables=db.tables(QSql::Views);
|
||||
|
||||
foreach(QString viewName, viewNames)
|
||||
{
|
||||
wasDropped = true;
|
||||
QString view=viewName;
|
||||
if ( db.driver()->isIdentifierEscaped(view, QSqlDriver::TableName))
|
||||
view = db.driver()->stripDelimiters(view, QSqlDriver::TableName);
|
||||
|
||||
if ( dbtables.contains( view, Qt::CaseInsensitive ) ) {
|
||||
foreach(const QString &view2, dbtables.filter(view, Qt::CaseInsensitive)) {
|
||||
if(view2.compare(view.section('.', -1, -1), Qt::CaseInsensitive) == 0) {
|
||||
view=db.driver()->escapeIdentifier(view2, QSqlDriver::TableName);
|
||||
wasDropped = q.exec( "drop view " + view);
|
||||
dbtables.removeAll(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !wasDropped )
|
||||
qWarning() << dbToString(db) << "unable to drop view" << viewName << ':' << q.lastError();
|
||||
// << "\nlast query:" << q.lastQuery()
|
||||
// << "\ndbtables:" << dbtables
|
||||
// << "\ndb.tables(QSql::Views):" << db.tables(QSql::Views);
|
||||
}
|
||||
}
|
||||
|
||||
static void safeDropView( QSqlDatabase db, const QString& tableName )
|
||||
{
|
||||
safeDropViews(db, QStringList() << tableName);
|
||||
}
|
||||
|
||||
// returns the type name of the blob datatype for the database db.
|
||||
// blobSize is only used if the db doesn't have a generic blob type
|
||||
static QString blobTypeName( QSqlDatabase db, int blobSize = 10000 )
|
||||
{
|
||||
if ( db.driverName().startsWith( "QMYSQL" ) )
|
||||
return "longblob";
|
||||
|
||||
if ( db.driverName().startsWith( "QPSQL" ) )
|
||||
return "bytea";
|
||||
|
||||
if ( db.driverName().startsWith( "QTDS" )
|
||||
|| isSqlServer( db )
|
||||
|| isMSAccess( db ) )
|
||||
return "image";
|
||||
|
||||
if ( db.driverName().startsWith( "QDB2" ) )
|
||||
return QString( "blob(%1)" ).arg( blobSize );
|
||||
|
||||
if ( db.driverName().startsWith( "QIBASE" ) )
|
||||
return QString( "blob sub_type 0 segment size 4096" );
|
||||
|
||||
if ( db.driverName().startsWith( "QOCI" )
|
||||
|| db.driverName().startsWith( "QSQLITE" ) )
|
||||
return "blob";
|
||||
|
||||
qDebug() << "tst_Databases::blobTypeName: Don't know the blob type for" << dbToString( db );
|
||||
|
||||
return "blob";
|
||||
}
|
||||
|
||||
static QString autoFieldName( QSqlDatabase db )
|
||||
{
|
||||
if ( db.driverName().startsWith( "QMYSQL" ) )
|
||||
return "AUTO_INCREMENT";
|
||||
if ( db.driverName().startsWith( "QTDS" ) )
|
||||
return "IDENTITY";
|
||||
/* if ( db.driverName().startsWith( "QPSQL" ) )
|
||||
return "SERIAL";*/
|
||||
// if ( db.driverName().startsWith( "QDB2" ) )
|
||||
// return "GENERATED BY DEFAULT AS IDENTITY";
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
static QByteArray printError( const QSqlError& err )
|
||||
{
|
||||
QString result;
|
||||
if(err.number() > 0)
|
||||
result += '(' + QString::number(err.number()) + ") ";
|
||||
result += '\'';
|
||||
if(!err.driverText().isEmpty())
|
||||
result += err.driverText() + "' || '";
|
||||
result += err.databaseText() + "'";
|
||||
return result.toLocal8Bit();
|
||||
}
|
||||
|
||||
static QByteArray printError( const QSqlError& err, const QSqlDatabase& db )
|
||||
{
|
||||
QString result(dbToString(db) + ": ");
|
||||
if(err.number() > 0)
|
||||
result += '(' + QString::number(err.number()) + ") ";
|
||||
result += '\'';
|
||||
if(!err.driverText().isEmpty())
|
||||
result += err.driverText() + "' || '";
|
||||
result += err.databaseText() + "'";
|
||||
return result.toLocal8Bit();
|
||||
}
|
||||
|
||||
static bool isSqlServer( QSqlDatabase db )
|
||||
{
|
||||
return db.databaseName().contains( "sql server", Qt::CaseInsensitive )
|
||||
|| db.databaseName().contains( "sqlserver", Qt::CaseInsensitive )
|
||||
|| db.databaseName().contains( "sql native client", Qt::CaseInsensitive )
|
||||
|| db.databaseName().contains( "bq-winserv", Qt::CaseInsensitive )
|
||||
|| db.hostName().contains( "bq-winserv", Qt::CaseInsensitive );
|
||||
}
|
||||
|
||||
static bool isMSAccess( QSqlDatabase db )
|
||||
{
|
||||
return db.databaseName().contains( "Access Driver", Qt::CaseInsensitive );
|
||||
}
|
||||
|
||||
static bool isPostgreSQL( QSqlDatabase db )
|
||||
{
|
||||
return db.driverName().startsWith("QPSQL") || (db.driverName().startsWith("QODBC") && ( db.databaseName().contains("PostgreSQL", Qt::CaseInsensitive) || db.databaseName().contains("pgsql", Qt::CaseInsensitive) ) );
|
||||
}
|
||||
|
||||
static bool isMySQL( QSqlDatabase db )
|
||||
{
|
||||
return db.driverName().startsWith("QMYSQL") || (db.driverName().startsWith("QODBC") && db.databaseName().contains("MySQL", Qt::CaseInsensitive) );
|
||||
}
|
||||
static bool isDB2( QSqlDatabase db )
|
||||
{
|
||||
return db.driverName().startsWith("QDB2") || (db.driverName().startsWith("QODBC") && db.databaseName().contains("db2", Qt::CaseInsensitive) );
|
||||
}
|
||||
|
||||
// -1 on fail, else Oracle version
|
||||
static int getOraVersion( QSqlDatabase db )
|
||||
{
|
||||
int ver = -1;
|
||||
QSqlQuery q( "SELECT banner FROM v$version", db );
|
||||
q.next();
|
||||
|
||||
QRegExp vers( "([0-9]+)\\.[0-9\\.]+[0-9]" );
|
||||
|
||||
if ( vers.indexIn( q.value( 0 ).toString() ) ) {
|
||||
bool ok;
|
||||
ver = vers.cap( 1 ).toInt( &ok );
|
||||
|
||||
if ( !ok )
|
||||
ver = -1;
|
||||
}
|
||||
|
||||
return ver;
|
||||
}
|
||||
|
||||
static QString getMySqlVersion( const QSqlDatabase &db )
|
||||
{
|
||||
QSqlQuery q(db);
|
||||
q.exec( "select version()" );
|
||||
if(q.next())
|
||||
return q.value( 0 ).toString();
|
||||
else
|
||||
return QString();
|
||||
}
|
||||
|
||||
static QString getPSQLVersion( const QSqlDatabase &db )
|
||||
{
|
||||
QSqlQuery q(db);
|
||||
q.exec( "select version()" );
|
||||
if(q.next())
|
||||
return q.value( 0 ).toString();
|
||||
else
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString sqLiteFileName() // Return a temporary file name for SQLite DB
|
||||
{
|
||||
const QString newFileName = m_sqLitePrefix + QLatin1Char('_')
|
||||
+ QString::number(m_sqLiteFiles.size()) + QLatin1String(".db");
|
||||
m_sqLiteFiles.append(newFileName);
|
||||
return newFileName;
|
||||
}
|
||||
|
||||
QStringList dbNames;
|
||||
int counter;
|
||||
|
||||
private:
|
||||
QString m_sqLitePrefix;
|
||||
QStringList m_sqLiteFiles;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
2545
tests/auto/qsqldatabase/tst_qsqldatabase.cpp
Normal file
2545
tests/auto/qsqldatabase/tst_qsqldatabase.cpp
Normal file
File diff suppressed because it is too large
Load diff
6
tests/benchmarks/CMakeLists.txt
Normal file
6
tests/benchmarks/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
# if(WITH_OPENGL AND OPENGL_FOUND)
|
||||
# add_subdirectory(opengl)
|
||||
# endif()
|
||||
# if(WITH_DBUS AND DBUS_FOUND)
|
||||
# add_subdirectory(dbus)
|
||||
# endif()
|
81
tests/benchmarks/README
Normal file
81
tests/benchmarks/README
Normal file
|
@ -0,0 +1,81 @@
|
|||
The most reliable way of running benchmarks is to do it in an otherwise idle
|
||||
system. On a busy system, the results will vary according to the other tasks
|
||||
demanding attention in the system.
|
||||
|
||||
We have managed to obtain quite reliable results by doing the following on
|
||||
Linux (and you need root):
|
||||
|
||||
- switching the scheduler to a Real-Time mode
|
||||
- setting the processor affinity to one single processor
|
||||
- disabling the other thread of the same core
|
||||
|
||||
This should work rather well for CPU-intensive tasks. A task that is in Real-
|
||||
Time mode will simply not be preempted by the OS. But if you make OS syscalls,
|
||||
especially I/O ones, your task will be de-scheduled. Note that this includes
|
||||
page faults, so if you can, make sure your benchmark's warmup code paths touch
|
||||
most of the data.
|
||||
|
||||
To do this you need a tool called schedtool (package schedtool), from
|
||||
http://freequaos.host.sk/schedtool/
|
||||
|
||||
From this point on, we are using CPU0 for all tasks:
|
||||
|
||||
If you have a Hyperthreaded multi-core processor (Core-i5 and Core-i7), you
|
||||
have to disable the other thread of the same core as CPU0. To discover which
|
||||
one it is:
|
||||
|
||||
$ cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list
|
||||
|
||||
This will print something like 0,4, meaning that CPUs 0 and 4 are sibling
|
||||
threads on the same core. So we'll turn CPU 4 off:
|
||||
|
||||
(as root)
|
||||
# echo 0 > /sys/devices/system/cpu/cpu4/online
|
||||
|
||||
To turn it back on, echo 1 into the same file.
|
||||
|
||||
To run a task on CPU 0 exclusively, using FIFO RT priority 10, you run the
|
||||
following:
|
||||
|
||||
(as root)
|
||||
# schedtool -F -p 10 -a 1 -e ./taskname
|
||||
|
||||
For example:
|
||||
# schedtool -F -p 10 -a 1 -e ./tst_bench_qstring -tickcounter
|
||||
|
||||
Warning: if your task livelocks or takes far too long to complete, your system
|
||||
may be unusable for a long time, especially if you don't have other cores to
|
||||
run stuff on. To prevent that, run it before schedtool and time it.
|
||||
|
||||
You can also limit the CPU time that the task is allowed to take. Run in the
|
||||
same shell as you'll run schedtool:
|
||||
|
||||
$ ulimit -s 300
|
||||
To limit to 300 seconds (5 minutes)
|
||||
|
||||
If your task runs away, it will get a SIGXCPU after consuming 5 minutes of CPU
|
||||
time (5 minutes running at 100%).
|
||||
|
||||
If your app is multithreaded, you may want to give it more CPUs, like CPU0 and
|
||||
CPU1 with -a 3 (it's a bitmask).
|
||||
|
||||
For best results, you should disable ALL other cores and threads of the same
|
||||
processor. The new Core-i7 have one processor with 4 cores,
|
||||
each core can run 2 threads; the older Mac Pros have two processors with 4
|
||||
cores each. So on those Mac Pros, you'd disable cores 1, 2 and 3, while on the
|
||||
Core-i7, you'll need to disable all other CPUs.
|
||||
|
||||
However, disabling just the sibling thread seems to produce very reliable
|
||||
results for me already, with variance often below 0.5% (even though there are
|
||||
some measurable spikes).
|
||||
|
||||
Other things to try:
|
||||
|
||||
Running the benchmark with highest priority, i.e. "sudo nice -19"
|
||||
usually produces stable results on some machines. If the benchmark also
|
||||
involves displaying something on the screen (on X11), running it with
|
||||
"-sync" is a must. Though, in that case the "real" cost is not correct,
|
||||
but it is useful to discover regressions.
|
||||
|
||||
Also; not many people know about ionice (1)
|
||||
ionice - get/set program io scheduling class and priority
|
3
tests/benchmarks/core/codecs/qtextcodec/CMakeLists.txt
Normal file
3
tests/benchmarks/core/codecs/qtextcodec/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_qtextcodec
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
179
tests/benchmarks/core/codecs/qtextcodec/main.cpp
Normal file
179
tests/benchmarks/core/codecs/qtextcodec/main.cpp
Normal file
|
@ -0,0 +1,179 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#include <QTextCodec>
|
||||
#include <QFile>
|
||||
#include <qtest.h>
|
||||
|
||||
Q_DECLARE_METATYPE(QList<QByteArray>)
|
||||
Q_DECLARE_METATYPE(QTextCodec *)
|
||||
|
||||
class tst_QTextCodec: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void codecForName() const;
|
||||
void codecForName_data() const;
|
||||
void codecForMib() const;
|
||||
void fromUnicode_data() const;
|
||||
void fromUnicode() const;
|
||||
void toUnicode_data() const;
|
||||
void toUnicode() const;
|
||||
};
|
||||
|
||||
void tst_QTextCodec::codecForName() const
|
||||
{
|
||||
QFETCH(QList<QByteArray>, codecs);
|
||||
|
||||
QBENCHMARK {
|
||||
foreach(const QByteArray& c, codecs) {
|
||||
QVERIFY(QTextCodec::codecForName(c));
|
||||
QVERIFY(QTextCodec::codecForName(c + "-"));
|
||||
}
|
||||
foreach(const QByteArray& c, codecs) {
|
||||
QVERIFY(QTextCodec::codecForName(c + "+"));
|
||||
QVERIFY(QTextCodec::codecForName(c + "*"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QTextCodec::codecForName_data() const
|
||||
{
|
||||
QTest::addColumn<QList<QByteArray> >("codecs");
|
||||
|
||||
QTest::newRow("all") << QTextCodec::availableCodecs();
|
||||
QTest::newRow("many utf-8") << (QList<QByteArray>()
|
||||
<< "utf-8" << "utf-8" << "utf-8" << "utf-8" << "utf-8"
|
||||
<< "utf-8" << "utf-8" << "utf-8" << "utf-8" << "utf-8"
|
||||
<< "utf-8" << "utf-8" << "utf-8" << "utf-8" << "utf-8"
|
||||
<< "utf-8" << "utf-8" << "utf-8" << "utf-8" << "utf-8"
|
||||
<< "utf-8" << "utf-8" << "utf-8" << "utf-8" << "utf-8"
|
||||
<< "utf-8" << "utf-8" << "utf-8" << "utf-8" << "utf-8"
|
||||
<< "utf-8" << "utf-8" << "utf-8" << "utf-8" << "utf-8"
|
||||
<< "utf-8" << "utf-8" << "utf-8" << "utf-8" << "utf-8"
|
||||
<< "utf-8" << "utf-8" << "utf-8" << "utf-8" << "utf-8" );
|
||||
}
|
||||
|
||||
void tst_QTextCodec::codecForMib() const
|
||||
{
|
||||
QBENCHMARK {
|
||||
QTextCodec::codecForMib(106);
|
||||
QTextCodec::codecForMib(111);
|
||||
QTextCodec::codecForMib(106);
|
||||
QTextCodec::codecForMib(2254);
|
||||
QTextCodec::codecForMib(2255);
|
||||
QTextCodec::codecForMib(2256);
|
||||
QTextCodec::codecForMib(2257);
|
||||
QTextCodec::codecForMib(2258);
|
||||
QTextCodec::codecForMib(111);
|
||||
QTextCodec::codecForMib(2250);
|
||||
QTextCodec::codecForMib(2251);
|
||||
QTextCodec::codecForMib(2252);
|
||||
QTextCodec::codecForMib(106);
|
||||
QTextCodec::codecForMib(106);
|
||||
QTextCodec::codecForMib(106);
|
||||
QTextCodec::codecForMib(106);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QTextCodec::fromUnicode_data() const
|
||||
{
|
||||
QTest::addColumn<QTextCodec*>("codec");
|
||||
|
||||
QTest::newRow("utf-8") << QTextCodec::codecForName("utf-8");
|
||||
QTest::newRow("latin 1") << QTextCodec::codecForName("latin 1");
|
||||
QTest::newRow("utf-16") << QTextCodec::codecForName("utf16"); ;
|
||||
QTest::newRow("utf-32") << QTextCodec::codecForName("utf32");
|
||||
QTest::newRow("latin15") << QTextCodec::codecForName("iso-8859-15");
|
||||
QTest::newRow("eucKr") << QTextCodec::codecForName("eucKr");
|
||||
}
|
||||
|
||||
|
||||
void tst_QTextCodec::fromUnicode() const
|
||||
{
|
||||
QFETCH(QTextCodec*, codec);
|
||||
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();
|
||||
QString s = QString::fromUtf8(d, size);
|
||||
s = s + s + s;
|
||||
s = s + s + s;
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 10; i ++)
|
||||
codec->fromUnicode(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tst_QTextCodec::toUnicode_data() const
|
||||
{
|
||||
fromUnicode_data();
|
||||
}
|
||||
|
||||
|
||||
void tst_QTextCodec::toUnicode() const
|
||||
{
|
||||
QFETCH(QTextCodec*, codec);
|
||||
QFile file(SRCDIR "utf-8.txt");
|
||||
QVERIFY(file.open(QFile::ReadOnly));
|
||||
QByteArray data = file.readAll();
|
||||
const char *d = data.constData();
|
||||
int size = data.size();
|
||||
QString s = QString::fromUtf8(d, size);
|
||||
s = s + s + s;
|
||||
s = s + s + s;
|
||||
QByteArray orig = codec->fromUnicode(s);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 10; i ++)
|
||||
codec->toUnicode(orig);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QTEST_MAIN(tst_QTextCodec)
|
||||
|
||||
#include "moc_main.cpp"
|
72
tests/benchmarks/core/codecs/qtextcodec/utf-8.txt
Normal file
72
tests/benchmarks/core/codecs/qtextcodec/utf-8.txt
Normal file
|
@ -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
|
200
tests/benchmarks/core/io/qdir/10000/bench_qdir_10000.cpp
Normal file
200
tests/benchmarks/core/io/qdir/10000/bench_qdir_10000.cpp
Normal file
|
@ -0,0 +1,200 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtCore/QDirIterator>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <sys/stat.h>
|
||||
# include <sys/types.h>
|
||||
# include <dirent.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
class bench_QDir_10000 : 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.next();
|
||||
dit.fileInfo().isDir();
|
||||
dit.fileInfo().size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.next();
|
||||
dit.fileInfo().isDir();
|
||||
dit.fileInfo().size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
QDir testdir(QDir::tempPath() + QLatin1String("/test_speed"));
|
||||
#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
|
||||
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(bench_QDir_10000)
|
||||
|
||||
#include "10000/moc_bench_qdir_10000.cpp"
|
8
tests/benchmarks/core/io/qdir/CMakeLists.txt
Normal file
8
tests/benchmarks/core/io/qdir/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
katie_test(bench_qdir_10000
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/10000/bench_qdir_10000.cpp
|
||||
)
|
||||
|
||||
katie_test(bench_qdir_tree
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tree/bench_qdir_tree.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tree/bench_qdir_tree.qrc
|
||||
)
|
11963
tests/benchmarks/core/io/qdir/tree/4.6.0-list.txt
Normal file
11963
tests/benchmarks/core/io/qdir/tree/4.6.0-list.txt
Normal file
File diff suppressed because it is too large
Load diff
242
tests/benchmarks/core/io/qdir/tree/bench_qdir_tree.cpp
Normal file
242
tests/benchmarks/core/io/qdir/tree/bench_qdir_tree.cpp
Normal file
|
@ -0,0 +1,242 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtTest/QTest>
|
||||
|
||||
#include <QDirIterator>
|
||||
#include <QFile>
|
||||
#include <QString>
|
||||
#include <QStack>
|
||||
|
||||
#include "../../../../../shared/filesystem.h"
|
||||
|
||||
class bench_QDir_tree
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
bench_QDir_tree()
|
||||
: prefix("./test-tree/"),
|
||||
musicprefix(QLatin1String("music")),
|
||||
photoprefix(QLatin1String("photos")),
|
||||
sourceprefix(QLatin1String("source")),
|
||||
musicsize(0),
|
||||
photosize(0),
|
||||
sourcesize(0)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
QByteArray prefix;
|
||||
QString musicprefix;
|
||||
QString photoprefix;
|
||||
QString sourceprefix;
|
||||
qint64 musicsize;
|
||||
qint64 photosize;
|
||||
qint64 sourcesize;
|
||||
|
||||
private slots:
|
||||
void initTestCase()
|
||||
{
|
||||
QFile list(":/4.6.0-list.txt");
|
||||
QVERIFY(list.open(QIODevice::ReadOnly | QIODevice::Text));
|
||||
|
||||
QVERIFY(fs.createDirectory(prefix));
|
||||
|
||||
QStack<QByteArray> stack;
|
||||
QByteArray line;
|
||||
Q_FOREVER {
|
||||
char ch;
|
||||
if (!list.getChar(&ch))
|
||||
break;
|
||||
if (ch != ' ') {
|
||||
line.append(ch);
|
||||
continue;
|
||||
}
|
||||
|
||||
int pop = 1;
|
||||
if (!line.isEmpty())
|
||||
pop = line.toInt();
|
||||
|
||||
while (pop) {
|
||||
stack.pop();
|
||||
--pop;
|
||||
}
|
||||
|
||||
line = list.readLine();
|
||||
line.chop(1);
|
||||
stack.push(line);
|
||||
|
||||
line = prefix;
|
||||
Q_FOREACH(const QByteArray &pathElement, stack)
|
||||
line += pathElement;
|
||||
|
||||
if (line.endsWith('/'))
|
||||
QVERIFY(fs.createDirectory(line));
|
||||
else
|
||||
QVERIFY(fs.createFile(line));
|
||||
|
||||
line.clear();
|
||||
}
|
||||
|
||||
//Use case: music collection - 10 files in 100 directories (albums)
|
||||
QVERIFY(fs.createDirectory(musicprefix));
|
||||
for (int i=0;i<1000;i++) {
|
||||
if ((i % 10) == 0)
|
||||
QVERIFY(fs.createDirectory(QString("%1/directory%2").arg(musicprefix).arg(i/10)));
|
||||
qint64 size = fs.createFileWithContent(QString("%1/directory%2/file%3").arg(musicprefix).arg(i/10).arg(i));
|
||||
QVERIFY(size > 0);
|
||||
musicsize += size;
|
||||
}
|
||||
//Use case: photos - 1000 files in 1 directory
|
||||
QVERIFY(fs.createDirectory(photoprefix));
|
||||
for (int i=0;i<1000;i++) {
|
||||
qint64 size = fs.createFileWithContent(QString("%1/file%2").arg(photoprefix).arg(i));
|
||||
QVERIFY(size > 0);
|
||||
photosize += size;
|
||||
}
|
||||
//Use case: source - 10 files in 10 subdirectories in 10 directories (1000 total)
|
||||
QVERIFY(fs.createDirectory(sourceprefix));
|
||||
for (int i=0;i<1000;i++) {
|
||||
if ((i % 100) == 0)
|
||||
QVERIFY(fs.createDirectory(QString("%1/directory%2").arg(sourceprefix).arg(i/100)));
|
||||
if ((i % 10) == 0)
|
||||
QVERIFY(fs.createDirectory(QString("%1/directory%2/subdirectory%3").arg(sourceprefix).arg(i/100).arg(i/10)));
|
||||
qint64 size = fs.createFileWithContent(QString("%1/directory%2/subdirectory%3/file%4").arg(sourceprefix).arg(i/100).arg(i/10).arg(i));
|
||||
QVERIFY(size > 0);
|
||||
sourcesize += size;
|
||||
}
|
||||
}
|
||||
|
||||
void fileSearch_data() const
|
||||
{
|
||||
QTest::addColumn<QStringList>("nameFilters");
|
||||
QTest::addColumn<int>("filter");
|
||||
QTest::addColumn<int>("entryCount");
|
||||
|
||||
QTest::newRow("*.cpp") << QStringList("*.cpp")
|
||||
<< int(QDir::Files)
|
||||
<< 3813;
|
||||
|
||||
QTest::newRow("executables") << QStringList("*")
|
||||
<< int(QDir::Executable | QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot)
|
||||
<< 543;
|
||||
}
|
||||
|
||||
void fileSearch() const
|
||||
{
|
||||
QFETCH(QStringList, nameFilters);
|
||||
QFETCH(int, filter);
|
||||
QFETCH(int, entryCount);
|
||||
|
||||
int count = 0;
|
||||
QBENCHMARK {
|
||||
// Recursive directory iteration
|
||||
QDirIterator iterator(prefix, nameFilters, QDir::Filter(filter),
|
||||
QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
|
||||
|
||||
count = 0;
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
++count;
|
||||
}
|
||||
|
||||
QCOMPARE(count, entryCount);
|
||||
}
|
||||
|
||||
QCOMPARE(count, entryCount);
|
||||
}
|
||||
|
||||
void traverseDirectory() const
|
||||
{
|
||||
int count = 0;
|
||||
QBENCHMARK {
|
||||
QDirIterator iterator(prefix,
|
||||
QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System,
|
||||
QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
|
||||
|
||||
count = 0;
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
++count;
|
||||
}
|
||||
|
||||
QCOMPARE(count, 11963);
|
||||
}
|
||||
|
||||
QCOMPARE(count, 11963);
|
||||
}
|
||||
|
||||
void thousandFiles_data() const
|
||||
{
|
||||
QTest::addColumn<QString>("dirName");
|
||||
QTest::addColumn<qint64>("expectedSize");
|
||||
QTest::newRow("music") << musicprefix << musicsize;
|
||||
QTest::newRow("photos") << photoprefix << photosize;
|
||||
QTest::newRow("src") << sourceprefix << sourcesize;
|
||||
}
|
||||
|
||||
void thousandFiles() const
|
||||
{
|
||||
QFETCH(QString, dirName);
|
||||
QFETCH(qint64, expectedSize);
|
||||
QBENCHMARK {
|
||||
qint64 totalsize = 0;
|
||||
int count = 0;
|
||||
QDirIterator iter(dirName, QDir::Files, QDirIterator::Subdirectories);
|
||||
while(iter.hasNext()) {
|
||||
iter.next();
|
||||
count++;
|
||||
totalsize += iter.fileInfo().size();
|
||||
}
|
||||
QCOMPARE(count, 1000);
|
||||
QCOMPARE(totalsize, expectedSize);
|
||||
}
|
||||
}
|
||||
private:
|
||||
FileSystem fs;
|
||||
};
|
||||
|
||||
QTEST_MAIN(bench_QDir_tree)
|
||||
|
||||
#include "tree/moc_bench_qdir_tree.cpp"
|
||||
#include "tree/qrc_bench_qdir_tree.cpp"
|
5
tests/benchmarks/core/io/qdir/tree/bench_qdir_tree.qrc
Normal file
5
tests/benchmarks/core/io/qdir/tree/bench_qdir_tree.qrc
Normal file
|
@ -0,0 +1,5 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>4.6.0-list.txt</file>
|
||||
</qresource>
|
||||
</RCC>
|
5
tests/benchmarks/core/io/qdiriterator/CMakeLists.txt
Normal file
5
tests/benchmarks/core/io/qdiriterator/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
katie_test(tst_bench_qdiriterator
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/qfilesystemiterator.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/qfilesystemiterator.h
|
||||
)
|
252
tests/benchmarks/core/io/qdiriterator/main.cpp
Normal file
252
tests/benchmarks/core/io/qdiriterator/main.cpp
Normal file
|
@ -0,0 +1,252 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#include <QDebug>
|
||||
#include <QDirIterator>
|
||||
#include <QString>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
# include <windows.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/core";
|
||||
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
|
||||
wchar_t wPath[MAX_PATH];
|
||||
path.toWCharArray(wPath);
|
||||
count = posix_helper(wPath);
|
||||
#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 "moc_main.cpp"
|
678
tests/benchmarks/core/io/qdiriterator/qfilesystemiterator.cpp
Normal file
678
tests/benchmarks/core/io/qdiriterator/qfilesystemiterator.cpp
Normal file
|
@ -0,0 +1,678 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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];
|
||||
QString::fromAscii(path).toWCharArray(szSearchPath);
|
||||
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
|
97
tests/benchmarks/core/io/qdiriterator/qfilesystemiterator.h
Normal file
97
tests/benchmarks/core/io/qdiriterator/qfilesystemiterator.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QFILESYSTEMITERATOR_H
|
||||
#define QFILESYSTEMITERATOR_H
|
||||
|
||||
#include <QtCore/qdir.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
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
|
9
tests/benchmarks/core/io/qfile/CMakeLists.txt
Normal file
9
tests/benchmarks/core/io/qfile/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
katie_test(tst_bench_qfile
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
||||
|
||||
if(KATIE_PLATFORM STREQUAL "wince")
|
||||
set_target_properties(tst_bench_qfile PROPERTIES PRIVATE
|
||||
COMPILE_DEFINITIONS -D_CRT_SECURE_NO_WARNINGS
|
||||
)
|
||||
endif()
|
787
tests/benchmarks/core/io/qfile/main.cpp
Normal file
787
tests/benchmarks/core/io/qfile/main.cpp
Normal file
|
@ -0,0 +1,787 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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>
|
||||
#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[] = {int(TF_SIZE*0.52),
|
||||
int(TF_SIZE*0.23),
|
||||
int(TF_SIZE*0.73),
|
||||
int(TF_SIZE*0.77),
|
||||
int(TF_SIZE*0.80),
|
||||
int(TF_SIZE*0.12),
|
||||
int(TF_SIZE*0.53),
|
||||
int(TF_SIZE*0.21),
|
||||
int(TF_SIZE*0.27),
|
||||
int(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();
|
||||
|
||||
void writeFileSequential_data();
|
||||
void writeFileSequential();
|
||||
void writeFileBackwards_data();
|
||||
void writeFileBackwards();
|
||||
void writeFileSequentialWithSeeks_data();
|
||||
void writeFileSequentialWithSeeks();
|
||||
|
||||
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();
|
||||
|
||||
#if defined(Q_OS_SYMBIAN) || defined(Q_WS_WINCE)
|
||||
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;
|
||||
}
|
||||
|
||||
void tst_qfile::writeFileSequential_data()
|
||||
{
|
||||
QTest::addColumn<int>("blockSize");
|
||||
QTest::addColumn<QString>("path");
|
||||
|
||||
QTest::newRow("internal 16b") << 16 << QDir::tempPath();
|
||||
QTest::newRow("internal 512b") << 512 << QDir::tempPath();
|
||||
QTest::newRow("internal 4k") << 4096 << QDir::tempPath();
|
||||
QTest::newRow("internal 16k") << 16384 << QDir::tempPath();
|
||||
QTest::newRow("internal 64k") << 65536 << QDir::tempPath();
|
||||
|
||||
//slow media (e.g. SD card)
|
||||
QString externalPath;
|
||||
#ifdef Q_OS_SYMBIAN
|
||||
externalPath = "E:/";
|
||||
#endif
|
||||
if (!externalPath.isEmpty()) {
|
||||
QTest::newRow("external 16b") << 16 << externalPath;
|
||||
QTest::newRow("external 512b") << 512 << externalPath;
|
||||
QTest::newRow("external 4k") << 4096 << externalPath;
|
||||
QTest::newRow("external 16k") << 16384 << externalPath;
|
||||
QTest::newRow("external 64k") << 65536 << externalPath;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qfile::writeFileSequential()
|
||||
{
|
||||
const qint64 limit = 1024 * 1024;
|
||||
QFETCH(int, blockSize);
|
||||
QFETCH(QString, path);
|
||||
QTemporaryFile f;
|
||||
f.setFileTemplate(path);
|
||||
QByteArray block;
|
||||
block.fill('@', blockSize);
|
||||
QBENCHMARK {
|
||||
QVERIFY(f.open());
|
||||
for (qint64 pos = 0; pos < limit; pos += blockSize) {
|
||||
QVERIFY(f.write(block));
|
||||
}
|
||||
QVERIFY(f.flush());
|
||||
QCOMPARE(f.size(), limit);
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qfile::writeFileBackwards_data()
|
||||
{
|
||||
writeFileSequential_data();
|
||||
}
|
||||
|
||||
void tst_qfile::writeFileBackwards()
|
||||
{
|
||||
const qint64 limit = 1024 * 1024;
|
||||
QFETCH(int, blockSize);
|
||||
QFETCH(QString, path);
|
||||
QTemporaryFile f;
|
||||
f.setFileTemplate(path);
|
||||
QByteArray block;
|
||||
block.fill('@', blockSize);
|
||||
QBENCHMARK {
|
||||
QVERIFY(f.open());
|
||||
for (qint64 pos = limit - blockSize; pos >= 0; pos -= blockSize) {
|
||||
QVERIFY(f.seek(pos));
|
||||
QVERIFY(f.write(block));
|
||||
}
|
||||
QVERIFY(f.flush());
|
||||
QCOMPARE(f.size(), limit);
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qfile::writeFileSequentialWithSeeks_data()
|
||||
{
|
||||
writeFileSequential_data();
|
||||
}
|
||||
|
||||
void tst_qfile::writeFileSequentialWithSeeks()
|
||||
{
|
||||
const qint64 limit = 1024 * 1024;
|
||||
QFETCH(int, blockSize);
|
||||
QFETCH(QString, path);
|
||||
QTemporaryFile f;
|
||||
f.setFileTemplate(path);
|
||||
QByteArray block;
|
||||
block.fill('@', blockSize);
|
||||
QBENCHMARK {
|
||||
QVERIFY(f.open());
|
||||
for (qint64 pos = 0; pos < limit; pos += blockSize) {
|
||||
QVERIFY(f.seek(pos));
|
||||
QVERIFY(f.write(block));
|
||||
}
|
||||
QVERIFY(f.flush());
|
||||
QCOMPARE(f.size(), limit);
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qfile)
|
||||
|
||||
#include "moc_main.cpp"
|
3
tests/benchmarks/core/io/qfileinfo/CMakeLists.txt.broken
Normal file
3
tests/benchmarks/core/io/qfileinfo/CMakeLists.txt.broken
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_qfileinfo
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
125
tests/benchmarks/core/io/qfileinfo/main.cpp
Normal file
125
tests/benchmarks/core/io/qfileinfo/main.cpp
Normal file
|
@ -0,0 +1,125 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#include <QDebug>
|
||||
#include <qtest.h>
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QFile>
|
||||
|
||||
#include "qfsfileengine_p.h"
|
||||
#include "../../../../shared/filesystem.h"
|
||||
|
||||
class qfileinfo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void canonicalFileNamePerformance();
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
void symLinkTargetPerformanceLNK();
|
||||
void symLinkTargetPerformanceMounpoint();
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
void qfileinfo::symLinkTargetPerformanceLNK()
|
||||
{
|
||||
QVERIFY(QFile::link("file","link.lnk"));
|
||||
QFileInfo info("link.lnk");
|
||||
info.setCaching(false);
|
||||
QVERIFY(info.isSymLink());
|
||||
QString linkTarget;
|
||||
QBENCHMARK {
|
||||
for(int i=0; i<100; i++)
|
||||
linkTarget = info.readLink();
|
||||
}
|
||||
QVERIFY(QFile::remove("link.lnk"));
|
||||
}
|
||||
|
||||
void qfileinfo::symLinkTargetPerformanceMounpoint()
|
||||
{
|
||||
wchar_t buffer[MAX_PATH];
|
||||
QString rootPath = QDir::toNativeSeparators(QDir::rootPath());
|
||||
QVERIFY(GetVolumeNameForVolumeMountPointW(rootPath.utf16(), buffer, MAX_PATH));
|
||||
QString rootVolume = QString::fromWCharArray(buffer);
|
||||
QString mountpoint = "mountpoint";
|
||||
rootVolume.replace("\\\\?\\","\\??\\");
|
||||
FileSystem::createNtfsJunction(rootVolume, mountpoint);
|
||||
|
||||
QFileInfo info(mountpoint);
|
||||
info.setCaching(false);
|
||||
QVERIFY(info.isSymLink());
|
||||
QString linkTarget;
|
||||
QBENCHMARK {
|
||||
for(int i=0; i<100; i++)
|
||||
linkTarget = info.readLink();
|
||||
}
|
||||
QVERIFY(QDir().rmdir(mountpoint));
|
||||
}
|
||||
#endif
|
||||
|
||||
QTEST_MAIN(qfileinfo)
|
||||
|
||||
#include "moc_main.cpp"
|
3
tests/benchmarks/core/io/qiodevice/CMakeLists.txt
Normal file
3
tests/benchmarks/core/io/qiodevice/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_qiodevice
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
107
tests/benchmarks/core/io/qiodevice/main.cpp
Normal file
107
tests/benchmarks/core/io/qiodevice/main.cpp
Normal file
|
@ -0,0 +1,107 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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 "moc_main.cpp"
|
3
tests/benchmarks/core/io/qtemporaryfile/CMakeLists.txt
Normal file
3
tests/benchmarks/core/io/qtemporaryfile/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_qtemporaryfile
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
103
tests/benchmarks/core/io/qtemporaryfile/main.cpp
Normal file
103
tests/benchmarks/core/io/qtemporaryfile/main.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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 "moc_main.cpp"
|
9
tests/benchmarks/core/io/qurl/CMakeLists.txt
Normal file
9
tests/benchmarks/core/io/qurl/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
katie_test(tst_qurl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
||||
|
||||
if(KATIE_PLATFORM STREQUAL "wince")
|
||||
set_target_properties(tst_bench_qfile PROPERTIES PRIVATE
|
||||
COMPILE_DEFINITIONS -D_CRT_SECURE_NO_WARNINGS
|
||||
)
|
||||
endif()
|
244
tests/benchmarks/core/io/qurl/main.cpp
Normal file
244
tests/benchmarks/core/io/qurl/main.cpp
Normal file
|
@ -0,0 +1,244 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <qurl.h>
|
||||
#include <qtest.h>
|
||||
|
||||
class tst_qurl: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void emptyUrl();
|
||||
void relativeUrl();
|
||||
void absoluteUrl();
|
||||
void isRelative_data();
|
||||
void isRelative();
|
||||
void toLocalFile_data();
|
||||
void toLocalFile();
|
||||
void toString_data();
|
||||
void toString();
|
||||
void toEncoded_data();
|
||||
void toEncoded();
|
||||
void resolved_data();
|
||||
void resolved();
|
||||
void equality_data();
|
||||
void equality();
|
||||
void qmlPropertyWriteUseCase();
|
||||
|
||||
private:
|
||||
void generateFirstRunData();
|
||||
};
|
||||
|
||||
void tst_qurl::emptyUrl()
|
||||
{
|
||||
QBENCHMARK {
|
||||
QUrl url;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qurl::relativeUrl()
|
||||
{
|
||||
QBENCHMARK {
|
||||
QUrl url("pics/avatar.png");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qurl::absoluteUrl()
|
||||
{
|
||||
QBENCHMARK {
|
||||
QUrl url("/tmp/avatar.png");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qurl::generateFirstRunData()
|
||||
{
|
||||
QTest::addColumn<bool>("firstRun");
|
||||
|
||||
QTest::newRow("construction + first run") << true;
|
||||
QTest::newRow("subsequent runs") << false;
|
||||
}
|
||||
|
||||
void tst_qurl::isRelative_data()
|
||||
{
|
||||
generateFirstRunData();
|
||||
}
|
||||
|
||||
void tst_qurl::isRelative()
|
||||
{
|
||||
QFETCH(bool, firstRun);
|
||||
if (firstRun) {
|
||||
QBENCHMARK {
|
||||
QUrl url("pics/avatar.png");
|
||||
url.isRelative();
|
||||
}
|
||||
} else {
|
||||
QUrl url("pics/avatar.png");
|
||||
QBENCHMARK {
|
||||
url.isRelative();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qurl::toLocalFile_data()
|
||||
{
|
||||
generateFirstRunData();
|
||||
}
|
||||
|
||||
void tst_qurl::toLocalFile()
|
||||
{
|
||||
QFETCH(bool, firstRun);
|
||||
if (firstRun) {
|
||||
QBENCHMARK {
|
||||
QUrl url("/tmp/avatar.png");
|
||||
url.toLocalFile();
|
||||
}
|
||||
} else {
|
||||
QUrl url("/tmp/avatar.png");
|
||||
QBENCHMARK {
|
||||
url.toLocalFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qurl::toString_data()
|
||||
{
|
||||
generateFirstRunData();
|
||||
}
|
||||
|
||||
void tst_qurl::toString()
|
||||
{
|
||||
QFETCH(bool, firstRun);
|
||||
if(firstRun) {
|
||||
QBENCHMARK {
|
||||
QUrl url("pics/avatar.png");
|
||||
url.toString();
|
||||
}
|
||||
} else {
|
||||
QUrl url("pics/avatar.png");
|
||||
QBENCHMARK {
|
||||
url.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qurl::toEncoded_data()
|
||||
{
|
||||
generateFirstRunData();
|
||||
}
|
||||
|
||||
void tst_qurl::toEncoded()
|
||||
{
|
||||
QFETCH(bool, firstRun);
|
||||
if(firstRun) {
|
||||
QBENCHMARK {
|
||||
QUrl url("pics/avatar.png");
|
||||
url.toEncoded(QUrl::FormattingOption(0x100));
|
||||
}
|
||||
} else {
|
||||
QUrl url("pics/avatar.png");
|
||||
QBENCHMARK {
|
||||
url.toEncoded(QUrl::FormattingOption(0x100));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qurl::resolved_data()
|
||||
{
|
||||
generateFirstRunData();
|
||||
}
|
||||
|
||||
void tst_qurl::resolved()
|
||||
{
|
||||
QFETCH(bool, firstRun);
|
||||
if(firstRun) {
|
||||
QBENCHMARK {
|
||||
QUrl baseUrl("/home/user/");
|
||||
QUrl url("pics/avatar.png");
|
||||
baseUrl.resolved(url);
|
||||
}
|
||||
} else {
|
||||
QUrl baseUrl("/home/user/");
|
||||
QUrl url("pics/avatar.png");
|
||||
QBENCHMARK {
|
||||
baseUrl.resolved(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qurl::equality_data()
|
||||
{
|
||||
generateFirstRunData();
|
||||
}
|
||||
|
||||
void tst_qurl::equality()
|
||||
{
|
||||
QFETCH(bool, firstRun);
|
||||
if(firstRun) {
|
||||
QBENCHMARK {
|
||||
QUrl url("pics/avatar.png");
|
||||
QUrl url2("pics/avatar2.png");
|
||||
//url == url2;
|
||||
}
|
||||
} else {
|
||||
QUrl url("pics/avatar.png");
|
||||
QUrl url2("pics/avatar2.png");
|
||||
QBENCHMARK {
|
||||
url == url2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qurl::qmlPropertyWriteUseCase()
|
||||
{
|
||||
QUrl base("file:///home/user/qt/demos/declarative/samegame/SamegameCore/");
|
||||
QString str("pics/redStar.png");
|
||||
|
||||
QBENCHMARK {
|
||||
QUrl u = QUrl(str);
|
||||
if (!u.isEmpty() && u.isRelative())
|
||||
u = base.resolved(u);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qurl)
|
||||
|
||||
#include "moc_main.cpp"
|
3
tests/benchmarks/core/kernel/events/CMakeLists.txt
Normal file
3
tests/benchmarks/core/kernel/events/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_events
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
187
tests/benchmarks/core/kernel/events/main.cpp
Normal file
187
tests/benchmarks/core/kernel/events/main.cpp
Normal file
|
@ -0,0 +1,187 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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 "moc_main.cpp"
|
5
tests/benchmarks/core/kernel/qmetaobject/CMakeLists.txt
Normal file
5
tests/benchmarks/core/kernel/qmetaobject/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
katie_test(tst_bench_qmetaobject
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(tst_bench_qmetaobject KtGui)
|
264
tests/benchmarks/core/kernel/qmetaobject/main.cpp
Normal file
264
tests/benchmarks/core/kernel/qmetaobject/main.cpp
Normal file
|
@ -0,0 +1,264 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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 "moc_main.cpp"
|
3
tests/benchmarks/core/kernel/qmetatype/CMakeLists.txt
Normal file
3
tests/benchmarks/core/kernel/qmetatype/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_qmetatype
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tst_qmetatype.cpp
|
||||
)
|
286
tests/benchmarks/core/kernel/qmetatype/tst_qmetatype.cpp
Normal file
286
tests/benchmarks/core/kernel/qmetatype/tst_qmetatype.cpp
Normal file
|
@ -0,0 +1,286 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <qtest.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
|
||||
//TESTED_FILES=
|
||||
|
||||
class tst_QMetaType : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QMetaType();
|
||||
virtual ~tst_QMetaType();
|
||||
|
||||
private slots:
|
||||
void typeBuiltin_data();
|
||||
void typeBuiltin();
|
||||
void typeBuiltinNotNormalized_data();
|
||||
void typeBuiltinNotNormalized();
|
||||
void typeCustom();
|
||||
void typeCustomNotNormalized();
|
||||
void typeNotRegistered();
|
||||
void typeNotRegisteredNotNormalized();
|
||||
|
||||
void typeNameBuiltin_data();
|
||||
void typeNameBuiltin();
|
||||
void typeNameCustom();
|
||||
void typeNameNotRegistered();
|
||||
|
||||
void isRegisteredBuiltin_data();
|
||||
void isRegisteredBuiltin();
|
||||
void isRegisteredCustom();
|
||||
void isRegisteredNotRegistered();
|
||||
|
||||
void constructCoreType_data();
|
||||
void constructCoreType();
|
||||
void constructCoreTypeCopy_data();
|
||||
void constructCoreTypeCopy();
|
||||
};
|
||||
|
||||
tst_QMetaType::tst_QMetaType()
|
||||
{
|
||||
}
|
||||
|
||||
tst_QMetaType::~tst_QMetaType()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeBuiltin_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("typeName");
|
||||
for (int i = 0; i < QMetaType::User; ++i) {
|
||||
const char *name = QMetaType::typeName(i);
|
||||
if (name)
|
||||
QTest::newRow(name) << QByteArray(name);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeBuiltin()
|
||||
{
|
||||
QFETCH(QByteArray, typeName);
|
||||
const char *nm = typeName.constData();
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
QMetaType::type(nm);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeBuiltinNotNormalized_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("typeName");
|
||||
for (int i = 0; i < QMetaType::User; ++i) {
|
||||
const char *name = QMetaType::typeName(i);
|
||||
if (name)
|
||||
QTest::newRow(name) << QByteArray(name).append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeBuiltinNotNormalized()
|
||||
{
|
||||
QFETCH(QByteArray, typeName);
|
||||
const char *nm = typeName.constData();
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
QMetaType::type(nm);
|
||||
}
|
||||
}
|
||||
|
||||
struct Foo { int i; };
|
||||
|
||||
void tst_QMetaType::typeCustom()
|
||||
{
|
||||
qRegisterMetaType<Foo>("Foo");
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
QMetaType::type("Foo");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeCustomNotNormalized()
|
||||
{
|
||||
qRegisterMetaType<Foo>("Foo");
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
QMetaType::type("Foo ");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeNotRegistered()
|
||||
{
|
||||
Q_ASSERT(QMetaType::type("Bar") == 0);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
QMetaType::type("Bar");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeNotRegisteredNotNormalized()
|
||||
{
|
||||
Q_ASSERT(QMetaType::type("Bar") == 0);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
QMetaType::type("Bar ");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeNameBuiltin_data()
|
||||
{
|
||||
QTest::addColumn<int>("type");
|
||||
for (int i = 0; i < QMetaType::User; ++i) {
|
||||
const char *name = QMetaType::typeName(i);
|
||||
if (name)
|
||||
QTest::newRow(name) << i;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeNameBuiltin()
|
||||
{
|
||||
QFETCH(int, type);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 500000; ++i)
|
||||
QMetaType::typeName(type);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeNameCustom()
|
||||
{
|
||||
int type = qRegisterMetaType<Foo>("Foo");
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
QMetaType::typeName(type);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeNameNotRegistered()
|
||||
{
|
||||
// We don't care much about this case, but test it anyway.
|
||||
Q_ASSERT(QMetaType::typeName(-1) == 0);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 500000; ++i)
|
||||
QMetaType::typeName(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::isRegisteredBuiltin_data()
|
||||
{
|
||||
typeNameBuiltin_data();
|
||||
}
|
||||
|
||||
void tst_QMetaType::isRegisteredBuiltin()
|
||||
{
|
||||
QFETCH(int, type);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 500000; ++i)
|
||||
QMetaType::isRegistered(type);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::isRegisteredCustom()
|
||||
{
|
||||
int type = qRegisterMetaType<Foo>("Foo");
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
QMetaType::isRegistered(type);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::isRegisteredNotRegistered()
|
||||
{
|
||||
Q_ASSERT(QMetaType::typeName(-1) == 0);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
QMetaType::isRegistered(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::constructCoreType_data()
|
||||
{
|
||||
QTest::addColumn<int>("typeId");
|
||||
for (int i = 0; i <= QMetaType::LastCoreType; ++i)
|
||||
QTest::newRow(QMetaType::typeName(i)) << i;
|
||||
for (int i = QMetaType::FirstCoreExtType; i <= QMetaType::LastCoreExtType; ++i)
|
||||
QTest::newRow(QMetaType::typeName(i)) << i;
|
||||
// GUI types are tested in tst_QGuiMetaType.
|
||||
}
|
||||
|
||||
// Tests how fast QMetaType can default-construct and destroy a Qt
|
||||
// core type. The purpose of this benchmark is to measure the overhead
|
||||
// of using type id-based creation compared to creating the type
|
||||
// directly (i.e. "T *t = new T(); delete t;").
|
||||
void tst_QMetaType::constructCoreType()
|
||||
{
|
||||
QFETCH(int, typeId);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i) {
|
||||
void *data = QMetaType::construct(typeId, (void *)0);
|
||||
QMetaType::destroy(typeId, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::constructCoreTypeCopy_data()
|
||||
{
|
||||
constructCoreType_data();
|
||||
}
|
||||
|
||||
// Tests how fast QMetaType can copy-construct and destroy a Qt core
|
||||
// type. The purpose of this benchmark is to measure the overhead of
|
||||
// using type id-based creation compared to creating the type directly
|
||||
// (i.e. "T *t = new T(other); delete t;").
|
||||
void tst_QMetaType::constructCoreTypeCopy()
|
||||
{
|
||||
QFETCH(int, typeId);
|
||||
QVariant other(typeId, (void *)0);
|
||||
const void *copy = other.constData();
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i) {
|
||||
void *data = QMetaType::construct(typeId, copy);
|
||||
QMetaType::destroy(typeId, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QMetaType)
|
||||
|
||||
#include "moc_tst_qmetatype.cpp"
|
7
tests/benchmarks/core/kernel/qobject/CMakeLists.txt
Normal file
7
tests/benchmarks/core/kernel/qobject/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
katie_test(tst_bench_qobject
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/object.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/object.h
|
||||
)
|
||||
|
||||
target_link_libraries(tst_bench_qobject KtGui)
|
185
tests/benchmarks/core/kernel/qobject/main.cpp
Normal file
185
tests/benchmarks/core/kernel/qobject/main.cpp
Normal file
|
@ -0,0 +1,185 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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;
|
||||
QTest::newRow("unconnected signal") << 3;
|
||||
}
|
||||
|
||||
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 if (type == 2) {
|
||||
QBENCHMARK {
|
||||
multiObject.emitSignal0();
|
||||
}
|
||||
} else if (type == 3) {
|
||||
QBENCHMARK {
|
||||
singleObject.emitSignal1();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 "moc_main.cpp"
|
70
tests/benchmarks/core/kernel/qobject/object.cpp
Normal file
70
tests/benchmarks/core/kernel/qobject/object.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "object.h"
|
||||
|
||||
void Object::emitSignal0()
|
||||
{ emit signal0(); }
|
||||
void Object::emitSignal1()
|
||||
{ emit signal1(); }
|
||||
|
||||
|
||||
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()
|
||||
{ }
|
||||
|
||||
#include "moc_object.h"
|
76
tests/benchmarks/core/kernel/qobject/object.h
Normal file
76
tests/benchmarks/core/kernel/qobject/object.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#ifndef OBJECT_H
|
||||
#define OBJECT_H
|
||||
|
||||
#include <qobject.h>
|
||||
|
||||
class Object : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
void emitSignal0();
|
||||
void emitSignal1();
|
||||
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
|
|
@ -0,0 +1,3 @@
|
|||
katie_test(qtimer_vs_qmetaobject
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tst_qtimer_vs_qmetaobject.cpp
|
||||
)
|
|
@ -0,0 +1,96 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#define INVOKE_COUNT 10000
|
||||
|
||||
class qtimer_vs_qmetaobject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void testZeroTimerSingleShot();
|
||||
void testQueuedInvokeMethod();
|
||||
};
|
||||
|
||||
class InvokeCounter : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
InvokeCounter() : count(0) { };
|
||||
public slots:
|
||||
void invokeSlot() {
|
||||
count++;
|
||||
if (count == INVOKE_COUNT)
|
||||
QTestEventLoop::instance().exitLoop();
|
||||
}
|
||||
protected:
|
||||
int count;
|
||||
};
|
||||
|
||||
void qtimer_vs_qmetaobject::testZeroTimerSingleShot()
|
||||
{
|
||||
QBENCHMARK {
|
||||
InvokeCounter invokeCounter;
|
||||
for(int i = 0; i < INVOKE_COUNT; ++i) {
|
||||
QTimer::singleShot(0, &invokeCounter, SLOT(invokeSlot()));
|
||||
}
|
||||
QTestEventLoop::instance().enterLoop(10);
|
||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
}
|
||||
}
|
||||
|
||||
void qtimer_vs_qmetaobject::testQueuedInvokeMethod()
|
||||
{
|
||||
QBENCHMARK {
|
||||
InvokeCounter invokeCounter;
|
||||
for(int i = 0; i < INVOKE_COUNT; ++i) {
|
||||
QMetaObject::invokeMethod(&invokeCounter, "invokeSlot", Qt::QueuedConnection);
|
||||
}
|
||||
QTestEventLoop::instance().enterLoop(10);
|
||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(qtimer_vs_qmetaobject)
|
||||
|
||||
#include "moc_tst_qtimer_vs_qmetaobject.cpp"
|
5
tests/benchmarks/core/kernel/qvariant/CMakeLists.txt
Normal file
5
tests/benchmarks/core/kernel/qvariant/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
katie_test(tst_bench_qvariant
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tst_qvariant.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(tst_bench_qvariant KtGui)
|
272
tests/benchmarks/core/kernel/qvariant/tst_qvariant.cpp
Normal file
272
tests/benchmarks/core/kernel/qvariant/tst_qvariant.cpp
Normal file
|
@ -0,0 +1,272 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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 doubleVariantValue();
|
||||
void floatVariantValue();
|
||||
void rectVariantValue();
|
||||
void stringVariantValue();
|
||||
|
||||
void createCoreType_data();
|
||||
void createCoreType();
|
||||
void createCoreTypeCopy_data();
|
||||
void createCoreTypeCopy();
|
||||
};
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void tst_qvariant::doubleVariantValue()
|
||||
{
|
||||
QVariant v(0.0);
|
||||
QBENCHMARK {
|
||||
for(int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
v.toDouble();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qvariant::floatVariantValue()
|
||||
{
|
||||
QVariant v(0.0f);
|
||||
QBENCHMARK {
|
||||
for(int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
v.toFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qvariant::rectVariantValue()
|
||||
{
|
||||
QVariant v(QRect(1,2,3,4));
|
||||
QBENCHMARK {
|
||||
for(int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
v.toRect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qvariant::stringVariantValue()
|
||||
{
|
||||
QVariant v = QString();
|
||||
QBENCHMARK {
|
||||
for(int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
v.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qvariant::createCoreType_data()
|
||||
{
|
||||
QTest::addColumn<int>("typeId");
|
||||
for (int i = 0; i <= QMetaType::LastCoreType; ++i)
|
||||
QTest::newRow(QMetaType::typeName(i)) << i;
|
||||
for (int i = QMetaType::FirstCoreExtType; i <= QMetaType::LastCoreExtType; ++i)
|
||||
QTest::newRow(QMetaType::typeName(i)) << i;
|
||||
}
|
||||
|
||||
// Tests how fast a Qt core type can be default-constructed by a
|
||||
// QVariant. The purpose of this benchmark is to measure the overhead
|
||||
// of creating (and destroying) a QVariant compared to creating the
|
||||
// type directly.
|
||||
void tst_qvariant::createCoreType()
|
||||
{
|
||||
QFETCH(int, typeId);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < ITERATION_COUNT; ++i)
|
||||
QVariant(typeId, (void *)0);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qvariant::createCoreTypeCopy_data()
|
||||
{
|
||||
createCoreType_data();
|
||||
}
|
||||
|
||||
// Tests how fast a Qt core type can be copy-constructed by a
|
||||
// QVariant. The purpose of this benchmark is to measure the overhead
|
||||
// of creating (and destroying) a QVariant compared to creating the
|
||||
// type directly.
|
||||
void tst_qvariant::createCoreTypeCopy()
|
||||
{
|
||||
QFETCH(int, typeId);
|
||||
QVariant other(typeId, (void *)0);
|
||||
const void *copy = other.constData();
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < ITERATION_COUNT; ++i)
|
||||
QVariant(typeId, copy);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qvariant)
|
||||
|
||||
#include "moc_tst_qvariant.cpp"
|
3
tests/benchmarks/core/plugin/quuid/CMakeLists.txt
Normal file
3
tests/benchmarks/core/plugin/quuid/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_quuid
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tst_quuid.cpp
|
||||
)
|
192
tests/benchmarks/core/plugin/quuid/tst_quuid.cpp
Normal file
192
tests/benchmarks/core/plugin/quuid/tst_quuid.cpp
Normal file
|
@ -0,0 +1,192 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QUuid>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
class tst_bench_QUuid : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_bench_QUuid()
|
||||
{ }
|
||||
|
||||
private slots:
|
||||
void createUuid();
|
||||
void fromChar();
|
||||
void toString();
|
||||
void fromString();
|
||||
void toByteArray();
|
||||
void fromByteArray();
|
||||
void toRfc4122();
|
||||
void fromRfc4122();
|
||||
void toDataStream();
|
||||
void fromDataStream();
|
||||
void isNull();
|
||||
void operatorLess();
|
||||
void operatorMore();
|
||||
};
|
||||
|
||||
void tst_bench_QUuid::createUuid()
|
||||
{
|
||||
QBENCHMARK {
|
||||
QUuid::createUuid();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_bench_QUuid::fromChar()
|
||||
{
|
||||
QBENCHMARK {
|
||||
QUuid uuid("{67C8770B-44F1-410A-AB9A-F9B5446F13EE}");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_bench_QUuid::toString()
|
||||
{
|
||||
QUuid uuid = QUuid::createUuid();
|
||||
QBENCHMARK {
|
||||
uuid.toString();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_bench_QUuid::fromString()
|
||||
{
|
||||
QString string = "{67C8770B-44F1-410A-AB9A-F9B5446F13EE}";
|
||||
QBENCHMARK {
|
||||
QUuid uuid(string);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_bench_QUuid::toByteArray()
|
||||
{
|
||||
QUuid uuid = QUuid::createUuid();
|
||||
QBENCHMARK {
|
||||
uuid.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_bench_QUuid::fromByteArray()
|
||||
{
|
||||
QByteArray string = "{67C8770B-44F1-410A-AB9A-F9B5446F13EE}";
|
||||
QBENCHMARK {
|
||||
QUuid uuid(string);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_bench_QUuid::toRfc4122()
|
||||
{
|
||||
QUuid uuid = QUuid::createUuid();
|
||||
QBENCHMARK {
|
||||
uuid.toRfc4122();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_bench_QUuid::fromRfc4122()
|
||||
{
|
||||
QByteArray string = QByteArray::fromHex("67C8770B44F1410AAB9AF9B5446F13EE");
|
||||
QBENCHMARK {
|
||||
QUuid uuid = QUuid::fromRfc4122(string);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_bench_QUuid::toDataStream()
|
||||
{
|
||||
QUuid uuid1, uuid2;
|
||||
uuid1 = QUuid::createUuid();
|
||||
QByteArray ar;
|
||||
{
|
||||
QDataStream out(&ar,QIODevice::WriteOnly);
|
||||
QBENCHMARK {
|
||||
out << uuid1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_bench_QUuid::fromDataStream()
|
||||
{
|
||||
QUuid uuid1, uuid2;
|
||||
uuid1 = QUuid::createUuid();
|
||||
QByteArray ar;
|
||||
{
|
||||
QDataStream out(&ar,QIODevice::WriteOnly);
|
||||
out << uuid1;
|
||||
}
|
||||
{
|
||||
QDataStream in(&ar,QIODevice::ReadOnly);
|
||||
QBENCHMARK {
|
||||
in >> uuid2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_bench_QUuid::isNull()
|
||||
{
|
||||
QUuid uuid = QUuid();
|
||||
QBENCHMARK {
|
||||
uuid.isNull();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_bench_QUuid::operatorLess()
|
||||
{
|
||||
QUuid uuid1, uuid2;
|
||||
uuid1 = QUuid::createUuid();
|
||||
uuid2 = QUuid::createUuid();
|
||||
QBENCHMARK {
|
||||
uuid1 < uuid2;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_bench_QUuid::operatorMore()
|
||||
{
|
||||
QUuid uuid1, uuid2;
|
||||
uuid1 = QUuid::createUuid();
|
||||
uuid2 = QUuid::createUuid();
|
||||
QBENCHMARK {
|
||||
uuid1 > uuid2;
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_bench_QUuid);
|
||||
|
||||
#include "moc_tst_quuid.cpp"
|
3
tests/benchmarks/core/thread/qmutex/CMakeLists.txt
Normal file
3
tests/benchmarks/core/thread/qmutex/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_qmutex
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tst_qmutex.cpp
|
||||
)
|
453
tests/benchmarks/core/thread/qmutex/tst_qmutex.cpp
Normal file
453
tests/benchmarks/core/thread/qmutex/tst_qmutex.cpp
Normal file
|
@ -0,0 +1,453 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore/QtCore>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#if defined(Q_OS_UNIX)
|
||||
# include <pthread.h>
|
||||
# include <errno.h>
|
||||
typedef pthread_mutex_t NativeMutexType;
|
||||
void NativeMutexInitialize(NativeMutexType *mutex)
|
||||
{
|
||||
pthread_mutex_init(mutex, NULL);
|
||||
}
|
||||
void NativeMutexDestroy(NativeMutexType *mutex)
|
||||
{
|
||||
pthread_mutex_destroy(mutex);
|
||||
}
|
||||
void NativeMutexLock(NativeMutexType *mutex)
|
||||
{
|
||||
pthread_mutex_lock(mutex);
|
||||
}
|
||||
void NativeMutexUnlock(NativeMutexType *mutex)
|
||||
{
|
||||
pthread_mutex_unlock(mutex);
|
||||
}
|
||||
#elif defined(Q_OS_WIN)
|
||||
# define _WIN32_WINNT 0x0400
|
||||
# include <windows.h>
|
||||
typedef CRITICAL_SECTION NativeMutexType;
|
||||
void NativeMutexInitialize(NativeMutexType *mutex)
|
||||
{
|
||||
InitializeCriticalSection(mutex);
|
||||
}
|
||||
void NativeMutexDestroy(NativeMutexType *mutex)
|
||||
{
|
||||
DeleteCriticalSection(mutex);
|
||||
}
|
||||
void NativeMutexLock(NativeMutexType *mutex)
|
||||
{
|
||||
EnterCriticalSection(mutex);
|
||||
}
|
||||
void NativeMutexUnlock(NativeMutexType *mutex)
|
||||
{
|
||||
LeaveCriticalSection(mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
//TESTED_FILES=
|
||||
|
||||
class tst_QMutex : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
int threadCount;
|
||||
|
||||
public:
|
||||
// barriers for the contended tests
|
||||
static QSemaphore semaphore1, semaphore2, semaphore3, semaphore4;
|
||||
|
||||
tst_QMutex()
|
||||
{
|
||||
// at least 2 threads, even on single cpu/core machines
|
||||
threadCount = qMax(2, QThread::idealThreadCount());
|
||||
qDebug("thread count: %d", threadCount);
|
||||
}
|
||||
|
||||
private slots:
|
||||
void noThread_data();
|
||||
void noThread();
|
||||
|
||||
void constructionNative();
|
||||
void uncontendedNative();
|
||||
void constructionQMutex();
|
||||
void uncontendedQMutex();
|
||||
void uncontendedQMutexLocker();
|
||||
|
||||
void contendedNative_data();
|
||||
void contendedQMutex_data() { contendedNative_data(); }
|
||||
void contendedQMutexLocker_data() { contendedNative_data(); }
|
||||
|
||||
void contendedNative();
|
||||
void contendedQMutex();
|
||||
void contendedQMutexLocker();
|
||||
};
|
||||
|
||||
QSemaphore tst_QMutex::semaphore1;
|
||||
QSemaphore tst_QMutex::semaphore2;
|
||||
QSemaphore tst_QMutex::semaphore3;
|
||||
QSemaphore tst_QMutex::semaphore4;
|
||||
|
||||
void tst_QMutex::noThread_data()
|
||||
{
|
||||
QTest::addColumn<int>("t");
|
||||
|
||||
QTest::newRow("noLock") << 1;
|
||||
QTest::newRow("QMutexInline") << 2;
|
||||
QTest::newRow("QMutex") << 3;
|
||||
QTest::newRow("QMutexLocker") << 4;
|
||||
}
|
||||
|
||||
void tst_QMutex::noThread()
|
||||
{
|
||||
volatile int count = 0;
|
||||
const int N = 5000000;
|
||||
QMutex mtx;
|
||||
|
||||
QFETCH(int, t);
|
||||
switch(t) {
|
||||
case 1:
|
||||
QBENCHMARK {
|
||||
count = 0;
|
||||
for (int i = 0; i < N; i++) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
QBENCHMARK {
|
||||
count = 0;
|
||||
for (int i = 0; i < N; i++) {
|
||||
mtx.lockInline();
|
||||
count++;
|
||||
mtx.unlockInline();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
QBENCHMARK {
|
||||
count = 0;
|
||||
for (int i = 0; i < N; i++) {
|
||||
mtx.lock();
|
||||
count++;
|
||||
mtx.unlock();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
QBENCHMARK {
|
||||
count = 0;
|
||||
for (int i = 0; i < N; i++) {
|
||||
QMutexLocker locker(&mtx);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
QCOMPARE(int(count), N);
|
||||
}
|
||||
|
||||
void tst_QMutex::constructionNative()
|
||||
{
|
||||
QBENCHMARK {
|
||||
NativeMutexType mutex;
|
||||
NativeMutexInitialize(&mutex);
|
||||
NativeMutexDestroy(&mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMutex::uncontendedNative()
|
||||
{
|
||||
NativeMutexType mutex;
|
||||
NativeMutexInitialize(&mutex);
|
||||
QBENCHMARK {
|
||||
NativeMutexLock(&mutex);
|
||||
NativeMutexUnlock(&mutex);
|
||||
}
|
||||
NativeMutexDestroy(&mutex);
|
||||
}
|
||||
|
||||
void tst_QMutex::constructionQMutex()
|
||||
{
|
||||
QBENCHMARK {
|
||||
QMutex mutex;
|
||||
Q_UNUSED(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMutex::uncontendedQMutex()
|
||||
{
|
||||
QMutex mutex;
|
||||
QBENCHMARK {
|
||||
mutex.lock();
|
||||
mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMutex::uncontendedQMutexLocker()
|
||||
{
|
||||
QMutex mutex;
|
||||
QBENCHMARK {
|
||||
QMutexLocker locker(&mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMutex::contendedNative_data()
|
||||
{
|
||||
QTest::addColumn<int>("iterations");
|
||||
QTest::addColumn<int>("msleepDuration");
|
||||
QTest::addColumn<bool>("use2mutexes");
|
||||
|
||||
QTest::newRow("baseline") << 0 << -1 << false;
|
||||
|
||||
QTest::newRow("no msleep, 1 mutex") << 1000 << -1 << false;
|
||||
QTest::newRow("no msleep, 2 mutexes") << 1000 << -1 << true;
|
||||
QTest::newRow("msleep(0), 1 mutex") << 1000 << 0 << false;
|
||||
QTest::newRow("msleep(0), 2 mutexes") << 1000 << 0 << true;
|
||||
QTest::newRow("msleep(1), 1 mutex") << 10 << 1 << false;
|
||||
QTest::newRow("msleep(1), 2 mutexes") << 10 << 1 << true;
|
||||
QTest::newRow("msleep(2), 1 mutex") << 10 << 2 << false;
|
||||
QTest::newRow("msleep(2), 2 mutexes") << 10 << 2 << true;
|
||||
QTest::newRow("msleep(10), 1 mutex") << 10 << 10 << false;
|
||||
QTest::newRow("msleep(10), 2 mutexes") << 10 << 10 << true;
|
||||
}
|
||||
|
||||
class NativeMutexThread : public QThread
|
||||
{
|
||||
NativeMutexType *mutex1, *mutex2;
|
||||
int iterations, msleepDuration;
|
||||
bool use2mutexes;
|
||||
public:
|
||||
bool done;
|
||||
NativeMutexThread(NativeMutexType *mutex1, NativeMutexType *mutex2, int iterations, int msleepDuration, bool use2mutexes)
|
||||
: mutex1(mutex1), mutex2(mutex2), iterations(iterations), msleepDuration(msleepDuration), use2mutexes(use2mutexes), done(false)
|
||||
{ }
|
||||
void run() {
|
||||
forever {
|
||||
tst_QMutex::semaphore1.release();
|
||||
tst_QMutex::semaphore2.acquire();
|
||||
if (done)
|
||||
break;
|
||||
for (int i = 0; i < iterations; ++i) {
|
||||
NativeMutexLock(mutex1);
|
||||
if (use2mutexes)
|
||||
NativeMutexLock(mutex2);
|
||||
if (msleepDuration >= 0)
|
||||
msleep(msleepDuration);
|
||||
if (use2mutexes)
|
||||
NativeMutexUnlock(mutex2);
|
||||
NativeMutexUnlock(mutex1);
|
||||
|
||||
QThread::yieldCurrentThread();
|
||||
}
|
||||
tst_QMutex::semaphore3.release();
|
||||
tst_QMutex::semaphore4.acquire();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QMutex::contendedNative()
|
||||
{
|
||||
QFETCH(int, iterations);
|
||||
QFETCH(int, msleepDuration);
|
||||
QFETCH(bool, use2mutexes);
|
||||
|
||||
NativeMutexType mutex1, mutex2;
|
||||
NativeMutexInitialize(&mutex1);
|
||||
NativeMutexInitialize(&mutex2);
|
||||
|
||||
QVector<NativeMutexThread *> threads(threadCount);
|
||||
for (int i = 0; i < threads.count(); ++i) {
|
||||
threads[i] = new NativeMutexThread(&mutex1, &mutex2, iterations, msleepDuration, use2mutexes);
|
||||
threads[i]->start();
|
||||
}
|
||||
|
||||
QBENCHMARK {
|
||||
semaphore1.acquire(threadCount);
|
||||
semaphore2.release(threadCount);
|
||||
semaphore3.acquire(threadCount);
|
||||
semaphore4.release(threadCount);
|
||||
}
|
||||
|
||||
for (int i = 0; i < threads.count(); ++i)
|
||||
threads[i]->done = true;
|
||||
semaphore1.acquire(threadCount);
|
||||
semaphore2.release(threadCount);
|
||||
for (int i = 0; i < threads.count(); ++i)
|
||||
threads[i]->wait();
|
||||
qDeleteAll(threads);
|
||||
|
||||
NativeMutexDestroy(&mutex1);
|
||||
NativeMutexDestroy(&mutex2);
|
||||
}
|
||||
|
||||
class QMutexThread : public QThread
|
||||
{
|
||||
QMutex *mutex1, *mutex2;
|
||||
int iterations, msleepDuration;
|
||||
bool use2mutexes;
|
||||
public:
|
||||
bool done;
|
||||
QMutexThread(QMutex *mutex1, QMutex *mutex2, int iterations, int msleepDuration, bool use2mutexes)
|
||||
: mutex1(mutex1), mutex2(mutex2), iterations(iterations), msleepDuration(msleepDuration), use2mutexes(use2mutexes), done(false)
|
||||
{ }
|
||||
void run() {
|
||||
forever {
|
||||
tst_QMutex::semaphore1.release();
|
||||
tst_QMutex::semaphore2.acquire();
|
||||
if (done)
|
||||
break;
|
||||
for (int i = 0; i < iterations; ++i) {
|
||||
mutex1->lock();
|
||||
if (use2mutexes)
|
||||
mutex2->lock();
|
||||
if (msleepDuration >= 0)
|
||||
msleep(msleepDuration);
|
||||
if (use2mutexes)
|
||||
mutex2->unlock();
|
||||
mutex1->unlock();
|
||||
|
||||
QThread::yieldCurrentThread();
|
||||
}
|
||||
tst_QMutex::semaphore3.release();
|
||||
tst_QMutex::semaphore4.acquire();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QMutex::contendedQMutex()
|
||||
{
|
||||
QFETCH(int, iterations);
|
||||
QFETCH(int, msleepDuration);
|
||||
QFETCH(bool, use2mutexes);
|
||||
|
||||
QMutex mutex1, mutex2;
|
||||
|
||||
QVector<QMutexThread *> threads(threadCount);
|
||||
for (int i = 0; i < threads.count(); ++i) {
|
||||
threads[i] = new QMutexThread(&mutex1, &mutex2, iterations, msleepDuration, use2mutexes);
|
||||
threads[i]->start();
|
||||
}
|
||||
|
||||
QBENCHMARK {
|
||||
semaphore1.acquire(threadCount);
|
||||
semaphore2.release(threadCount);
|
||||
semaphore3.acquire(threadCount);
|
||||
semaphore4.release(threadCount);
|
||||
}
|
||||
|
||||
for (int i = 0; i < threads.count(); ++i)
|
||||
threads[i]->done = true;
|
||||
semaphore1.acquire(threadCount);
|
||||
semaphore2.release(threadCount);
|
||||
for (int i = 0; i < threads.count(); ++i)
|
||||
threads[i]->wait();
|
||||
qDeleteAll(threads);
|
||||
}
|
||||
|
||||
class QMutexLockerThread : public QThread
|
||||
{
|
||||
QMutex *mutex1, *mutex2;
|
||||
int iterations, msleepDuration;
|
||||
bool use2mutexes;
|
||||
public:
|
||||
bool done;
|
||||
QMutexLockerThread(QMutex *mutex1, QMutex *mutex2, int iterations, int msleepDuration, bool use2mutexes)
|
||||
: mutex1(mutex1), mutex2(mutex2), iterations(iterations), msleepDuration(msleepDuration), use2mutexes(use2mutexes), done(false)
|
||||
{ }
|
||||
void run() {
|
||||
forever {
|
||||
tst_QMutex::semaphore1.release();
|
||||
tst_QMutex::semaphore2.acquire();
|
||||
if (done)
|
||||
break;
|
||||
for (int i = 0; i < iterations; ++i) {
|
||||
{
|
||||
QMutexLocker locker1(mutex1);
|
||||
QMutexLocker locker2(use2mutexes ? mutex2 : 0);
|
||||
if (msleepDuration >= 0)
|
||||
msleep(msleepDuration);
|
||||
}
|
||||
|
||||
QThread::yieldCurrentThread();
|
||||
}
|
||||
tst_QMutex::semaphore3.release();
|
||||
tst_QMutex::semaphore4.acquire();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QMutex::contendedQMutexLocker()
|
||||
{
|
||||
QFETCH(int, iterations);
|
||||
QFETCH(int, msleepDuration);
|
||||
QFETCH(bool, use2mutexes);
|
||||
|
||||
QMutex mutex1, mutex2;
|
||||
|
||||
QVector<QMutexLockerThread *> threads(threadCount);
|
||||
for (int i = 0; i < threads.count(); ++i) {
|
||||
threads[i] = new QMutexLockerThread(&mutex1, &mutex2, iterations, msleepDuration, use2mutexes);
|
||||
threads[i]->start();
|
||||
}
|
||||
|
||||
QBENCHMARK {
|
||||
semaphore1.acquire(threadCount);
|
||||
semaphore2.release(threadCount);
|
||||
semaphore3.acquire(threadCount);
|
||||
semaphore4.release(threadCount);
|
||||
}
|
||||
|
||||
for (int i = 0; i < threads.count(); ++i)
|
||||
threads[i]->done = true;
|
||||
semaphore1.acquire(threadCount);
|
||||
semaphore2.release(threadCount);
|
||||
for (int i = 0; i < threads.count(); ++i)
|
||||
threads[i]->wait();
|
||||
qDeleteAll(threads);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QMutex)
|
||||
|
||||
#include "moc_tst_qmutex.cpp"
|
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_qthreadstorage
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tst_qthreadstorage.cpp
|
||||
)
|
|
@ -0,0 +1,125 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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 "moc_tst_qthreadstorage.cpp"
|
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_qwaitcondition
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tst_qwaitcondition.cpp
|
||||
)
|
|
@ -0,0 +1,211 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore/QtCore>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
class tst_QWaitCondition : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QWaitCondition()
|
||||
{
|
||||
}
|
||||
|
||||
private slots:
|
||||
void oscillate_data();
|
||||
void oscillate();
|
||||
|
||||
void thrash_data();
|
||||
void thrash();
|
||||
|
||||
public:
|
||||
static QWaitCondition local, remote;
|
||||
enum Turn {LocalTurn, RemoteTurn};
|
||||
static Turn turn;
|
||||
};
|
||||
|
||||
QWaitCondition tst_QWaitCondition::local;
|
||||
QWaitCondition tst_QWaitCondition::remote;
|
||||
tst_QWaitCondition::Turn tst_QWaitCondition::turn = tst_QWaitCondition::LocalTurn;
|
||||
|
||||
class OscillateThread : public QThread
|
||||
{
|
||||
public:
|
||||
bool m_done;
|
||||
bool m_useMutex;
|
||||
unsigned long m_timeout;
|
||||
bool m_wakeOne;
|
||||
int count;
|
||||
|
||||
OscillateThread(bool useMutex, unsigned long timeout, bool wakeOne)
|
||||
: m_done(false), m_useMutex(useMutex), m_timeout(timeout), m_wakeOne(wakeOne)
|
||||
{}
|
||||
void run()
|
||||
{
|
||||
QMutex mtx;
|
||||
QReadWriteLock rwl;
|
||||
count = 0;
|
||||
|
||||
forever {
|
||||
if (m_done)
|
||||
break;
|
||||
if (m_useMutex) {
|
||||
mtx.lock();
|
||||
while (tst_QWaitCondition::turn == tst_QWaitCondition::LocalTurn)
|
||||
tst_QWaitCondition::remote.wait(&mtx, m_timeout);
|
||||
mtx.unlock();
|
||||
} else {
|
||||
rwl.lockForWrite();
|
||||
while (tst_QWaitCondition::turn == tst_QWaitCondition::LocalTurn)
|
||||
tst_QWaitCondition::remote.wait(&rwl, m_timeout);
|
||||
rwl.unlock();
|
||||
}
|
||||
tst_QWaitCondition::turn = tst_QWaitCondition::LocalTurn;
|
||||
if (m_wakeOne)
|
||||
tst_QWaitCondition::local.wakeOne();
|
||||
else
|
||||
tst_QWaitCondition::local.wakeAll();
|
||||
count++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QWaitCondition::oscillate_data()
|
||||
{
|
||||
QTest::addColumn<bool>("useMutex");
|
||||
QTest::addColumn<unsigned long>("timeout");
|
||||
QTest::addColumn<bool>("wakeOne");
|
||||
|
||||
QTest::newRow("mutex, timeout, one") << true << 1000ul << true;
|
||||
QTest::newRow("readWriteLock, timeout, one") << false << 1000ul << true;
|
||||
QTest::newRow("mutex, timeout, all") << true << 1000ul << false;
|
||||
QTest::newRow("readWriteLock, timeout, all") << false << 1000ul << false;
|
||||
QTest::newRow("mutex, forever, one") << true << ULONG_MAX << true;
|
||||
QTest::newRow("readWriteLock, forever, one") << false << ULONG_MAX << true;
|
||||
QTest::newRow("mutex, forever, all") << true << ULONG_MAX << false;
|
||||
QTest::newRow("readWriteLock, forever, all") << false << ULONG_MAX << false;
|
||||
}
|
||||
|
||||
void tst_QWaitCondition::oscillate()
|
||||
{
|
||||
QMutex mtx;
|
||||
QReadWriteLock rwl;
|
||||
|
||||
QFETCH(bool, useMutex);
|
||||
QFETCH(unsigned long, timeout);
|
||||
QFETCH(bool, wakeOne);
|
||||
|
||||
turn = LocalTurn;
|
||||
OscillateThread thrd(useMutex, timeout, wakeOne);
|
||||
thrd.start();
|
||||
|
||||
QBENCHMARK {
|
||||
if (useMutex)
|
||||
mtx.lock();
|
||||
else
|
||||
rwl.lockForWrite();
|
||||
turn = RemoteTurn;
|
||||
if (wakeOne)
|
||||
remote.wakeOne();
|
||||
else
|
||||
remote.wakeAll();
|
||||
if (useMutex) {
|
||||
while (turn == RemoteTurn)
|
||||
local.wait(&mtx, timeout);
|
||||
mtx.unlock();
|
||||
} else {
|
||||
while (turn == RemoteTurn)
|
||||
local.wait(&rwl, timeout);
|
||||
rwl.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
thrd.m_done = true;
|
||||
remote.wakeAll();
|
||||
thrd.wait();
|
||||
|
||||
QCOMPARE(0, 0);
|
||||
}
|
||||
|
||||
void tst_QWaitCondition::thrash_data()
|
||||
{
|
||||
oscillate_data();
|
||||
}
|
||||
|
||||
void tst_QWaitCondition::thrash()
|
||||
{
|
||||
QMutex mtx;
|
||||
mtx.lock();
|
||||
|
||||
QFETCH(bool, useMutex);
|
||||
QFETCH(unsigned long, timeout);
|
||||
QFETCH(bool, wakeOne);
|
||||
|
||||
turn = LocalTurn;
|
||||
OscillateThread thrd(useMutex, timeout, wakeOne);
|
||||
thrd.start();
|
||||
local.wait(&mtx, 1000ul);
|
||||
mtx.unlock();
|
||||
|
||||
QBENCHMARK {
|
||||
turn = RemoteTurn;
|
||||
if (wakeOne)
|
||||
remote.wakeOne();
|
||||
else
|
||||
remote.wakeAll();
|
||||
}
|
||||
|
||||
thrd.m_done = true;
|
||||
turn = RemoteTurn;
|
||||
remote.wakeAll();
|
||||
thrd.wait();
|
||||
|
||||
QCOMPARE(0, 0);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QWaitCondition)
|
||||
|
||||
#include "moc_tst_qwaitcondition.cpp"
|
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_containers-associative
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
143
tests/benchmarks/core/tools/containers-associative/main.cpp
Normal file
143
tests/benchmarks/core/tools/containers-associative/main.cpp
Normal file
|
@ -0,0 +1,143 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#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 "moc_main.cpp"
|
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_containers-sequential
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
266
tests/benchmarks/core/tools/containers-sequential/main.cpp
Normal file
266
tests/benchmarks/core/tools/containers-sequential/main.cpp
Normal file
|
@ -0,0 +1,266 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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
|
||||
#if defined(Q_OS_SYMBIAN) || defined(Q_WS_WINCE)
|
||||
# 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 "moc_main.cpp"
|
3
tests/benchmarks/core/tools/qbytearray/CMakeLists.txt
Normal file
3
tests/benchmarks/core/tools/qbytearray/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_qbytearray
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
87
tests/benchmarks/core/tools/qbytearray/main.cpp
Normal file
87
tests/benchmarks/core/tools/qbytearray/main.cpp
Normal file
|
@ -0,0 +1,87 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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);
|
||||
|
||||
QByteArray ba;
|
||||
QBENCHMARK {
|
||||
QByteArray ba2(size, 'x');
|
||||
ba.append(ba2);
|
||||
ba.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(tst_qbytearray)
|
||||
|
||||
#include "moc_main.cpp"
|
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_qcontiguouscache
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
189
tests/benchmarks/core/tools/qcontiguouscache/main.cpp
Normal file
189
tests/benchmarks/core/tools/qcontiguouscache/main.cpp
Normal file
|
@ -0,0 +1,189 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QObject>
|
||||
#include <QTest>
|
||||
#include <QCache>
|
||||
#include <QContiguousCache>
|
||||
|
||||
#include <QDebug>
|
||||
#include <stdio.h>
|
||||
|
||||
class tst_QContiguousCache : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void asScrollingList();
|
||||
void cacheBenchmark();
|
||||
void contiguousCacheBenchmark();
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_QContiguousCache)
|
||||
|
||||
void tst_QContiguousCache::asScrollingList()
|
||||
{
|
||||
int i;
|
||||
QContiguousCache<int> c(10);
|
||||
|
||||
// Once allocated QContiguousCache should not
|
||||
// allocate any additional memory for non
|
||||
// complex data types.
|
||||
QBENCHMARK {
|
||||
// simulate scrolling in a list of items;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
QCOMPARE(c.available(), 10-i);
|
||||
c.append(i);
|
||||
}
|
||||
|
||||
QCOMPARE(c.firstIndex(), 0);
|
||||
QCOMPARE(c.lastIndex(), 9);
|
||||
QCOMPARE(c.first(), 0);
|
||||
QCOMPARE(c.last(), 9);
|
||||
QVERIFY(!c.containsIndex(-1));
|
||||
QVERIFY(!c.containsIndex(10));
|
||||
QCOMPARE(c.available(), 0);
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
QVERIFY(c.containsIndex(i));
|
||||
QCOMPARE(c.at(i), i);
|
||||
QCOMPARE(c[i], i);
|
||||
QCOMPARE(((const QContiguousCache<int>)c)[i], i);
|
||||
}
|
||||
|
||||
for (i = 10; i < 30; ++i)
|
||||
c.append(i);
|
||||
|
||||
QCOMPARE(c.firstIndex(), 20);
|
||||
QCOMPARE(c.lastIndex(), 29);
|
||||
QCOMPARE(c.first(), 20);
|
||||
QCOMPARE(c.last(), 29);
|
||||
QVERIFY(!c.containsIndex(19));
|
||||
QVERIFY(!c.containsIndex(30));
|
||||
QCOMPARE(c.available(), 0);
|
||||
|
||||
for (i = 20; i < 30; ++i) {
|
||||
QVERIFY(c.containsIndex(i));
|
||||
QCOMPARE(c.at(i), i);
|
||||
QCOMPARE(c[i], i);
|
||||
QCOMPARE(((const QContiguousCache<int> )c)[i], i);
|
||||
}
|
||||
|
||||
for (i = 19; i >= 10; --i)
|
||||
c.prepend(i);
|
||||
|
||||
QCOMPARE(c.firstIndex(), 10);
|
||||
QCOMPARE(c.lastIndex(), 19);
|
||||
QCOMPARE(c.first(), 10);
|
||||
QCOMPARE(c.last(), 19);
|
||||
QVERIFY(!c.containsIndex(9));
|
||||
QVERIFY(!c.containsIndex(20));
|
||||
QCOMPARE(c.available(), 0);
|
||||
|
||||
for (i = 10; i < 20; ++i) {
|
||||
QVERIFY(c.containsIndex(i));
|
||||
QCOMPARE(c.at(i), i);
|
||||
QCOMPARE(c[i], i);
|
||||
QCOMPARE(((const QContiguousCache<int> )c)[i], i);
|
||||
}
|
||||
|
||||
for (i = 200; i < 220; ++i)
|
||||
c.insert(i, i);
|
||||
|
||||
QCOMPARE(c.firstIndex(), 210);
|
||||
QCOMPARE(c.lastIndex(), 219);
|
||||
QCOMPARE(c.first(), 210);
|
||||
QCOMPARE(c.last(), 219);
|
||||
QVERIFY(!c.containsIndex(209));
|
||||
QVERIFY(!c.containsIndex(300));
|
||||
QCOMPARE(c.available(), 0);
|
||||
|
||||
for (i = 210; i < 220; ++i) {
|
||||
QVERIFY(c.containsIndex(i));
|
||||
QCOMPARE(c.at(i), i);
|
||||
QCOMPARE(c[i], i);
|
||||
QCOMPARE(((const QContiguousCache<int> )c)[i], i);
|
||||
}
|
||||
c.clear(); // needed to reset benchmark
|
||||
}
|
||||
|
||||
// from a specific bug that was encountered. 100 to 299 cached, attempted to cache 250 - 205 via insert, failed.
|
||||
// bug was that item at 150 would instead be item that should have been inserted at 250
|
||||
c.setCapacity(200);
|
||||
for (i = 100; i < 300; ++i)
|
||||
c.insert(i, i);
|
||||
for (i = 250; i <= 306; ++i)
|
||||
c.insert(i, 1000+i);
|
||||
for (i = 107; i <= 306; ++i) {
|
||||
QVERIFY(c.containsIndex(i));
|
||||
QCOMPARE(c.at(i), i < 250 ? i : 1000+i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Benchmarks must be near identical in tasks to be fair.
|
||||
QCache uses pointers to ints as its a requirement of QCache,
|
||||
whereas QContiguousCache doesn't support pointers (won't free them).
|
||||
Given the ability to use simple data types is a benefit, its
|
||||
fair. Although this obviously must take into account we are
|
||||
testing QContiguousCache use cases here, QCache has its own
|
||||
areas where it is the more sensible class to use.
|
||||
*/
|
||||
void tst_QContiguousCache::cacheBenchmark()
|
||||
{
|
||||
QBENCHMARK {
|
||||
QCache<int, int> cache;
|
||||
cache.setMaxCost(100);
|
||||
|
||||
for (int i = 0; i < 1000; i++)
|
||||
cache.insert(i, new int(i));
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QContiguousCache::contiguousCacheBenchmark()
|
||||
{
|
||||
QBENCHMARK {
|
||||
QContiguousCache<int> contiguousCache(100);
|
||||
for (int i = 0; i < 1000; i++)
|
||||
contiguousCache.insert(i, i);
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_main.cpp"
|
4
tests/benchmarks/core/tools/qhash/CMakeLists.txt
Normal file
4
tests/benchmarks/core/tools/qhash/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
katie_test(tst_hash
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/qhash_string.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/outofline.cpp
|
||||
)
|
195
tests/benchmarks/core/tools/qhash/data.txt
Normal file
195
tests/benchmarks/core/tools/qhash/data.txt
Normal file
|
@ -0,0 +1,195 @@
|
|||
.
|
||||
./corelib.pro
|
||||
./kernel
|
||||
./kernel/kernel.pro
|
||||
./kernel/qobject
|
||||
./kernel/qobject/main.cpp
|
||||
./kernel/qobject/object.cpp
|
||||
./kernel/qobject/object.h
|
||||
./kernel/qobject/Makefile
|
||||
./kernel/qobject/qobject.pro
|
||||
./kernel/qvariant
|
||||
./kernel/qvariant/tst_qvariant.cpp
|
||||
./kernel/qvariant/Makefile
|
||||
./kernel/qvariant/qvariant.pro
|
||||
./kernel/qtimer_vs_qmetaobject
|
||||
./kernel/qtimer_vs_qmetaobject/tst_qtimer_vs_qmetaobject.cpp
|
||||
./kernel/qtimer_vs_qmetaobject/Makefile
|
||||
./kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro
|
||||
./kernel/.pch
|
||||
./kernel/.pch/debug-shared
|
||||
./kernel/qmetaobject
|
||||
./kernel/qmetaobject/main.cpp
|
||||
./kernel/qmetaobject/qmetaobject.pro
|
||||
./kernel/qmetaobject/Makefile
|
||||
./kernel/Makefile
|
||||
./kernel/.obj
|
||||
./kernel/.obj/debug-shared
|
||||
./kernel/events
|
||||
./kernel/events/events.pro
|
||||
./kernel/events/main.cpp
|
||||
./kernel/events/Makefile
|
||||
./kernel/qmetatype
|
||||
./kernel/qmetatype/qmetatype.pro
|
||||
./kernel/qmetatype/Makefile
|
||||
./kernel/qmetatype/tst_qmetatype.cpp
|
||||
./codecs
|
||||
./codecs/qtextcodec
|
||||
./codecs/qtextcodec/qtextcodec.pro
|
||||
./codecs/qtextcodec/main.cpp
|
||||
./codecs/qtextcodec/Makefile
|
||||
./codecs/qtextcodec/utf-8.txt
|
||||
./codecs/codecs.pro
|
||||
./codecs/.pch
|
||||
./codecs/.pch/debug-shared
|
||||
./codecs/Makefile
|
||||
./codecs/.obj
|
||||
./codecs/.obj/debug-shared
|
||||
./.pch
|
||||
./.pch/debug-shared
|
||||
./tools
|
||||
./tools/tools.pro
|
||||
./tools/qregexp
|
||||
./tools/qregexp/qregexp.qrc
|
||||
./tools/qregexp/main.cpp
|
||||
./tools/qregexp/Makefile
|
||||
./tools/qregexp/qregexp.pro
|
||||
./tools/qvector
|
||||
./tools/qvector/tst_vector
|
||||
./tools/qvector/.pch
|
||||
./tools/qvector/.pch/debug-shared
|
||||
./tools/qvector/qrawvector.h
|
||||
./tools/qvector/main.cpp
|
||||
./tools/qvector/Makefile
|
||||
./tools/qvector/.moc
|
||||
./tools/qvector/.moc/release-shared
|
||||
./tools/qvector/.moc/release-shared/main.moc
|
||||
./tools/qvector/.obj
|
||||
./tools/qvector/.obj/release-shared
|
||||
./tools/qvector/.obj/release-shared/outofline.o
|
||||
./tools/qvector/.obj/release-shared/main.o
|
||||
./tools/qvector/outofline.cpp
|
||||
./tools/qvector/qvector.pro
|
||||
./tools/.pch
|
||||
./tools/.pch/debug-shared
|
||||
./tools/qstringbuilder
|
||||
./tools/qstringbuilder/main.cpp
|
||||
./tools/qstringbuilder/Makefile
|
||||
./tools/qstringbuilder/qstringbuilder.pro
|
||||
./tools/containers-sequential
|
||||
./tools/containers-sequential/containers-sequential.pro
|
||||
./tools/containers-sequential/main.cpp
|
||||
./tools/containers-sequential/Makefile
|
||||
./tools/qstring
|
||||
./tools/qstring/generatelist.pl
|
||||
./tools/qstring/data.h
|
||||
./tools/qstring/qstring.pro
|
||||
./tools/qstring/main.cpp
|
||||
./tools/qstring/data.cpp
|
||||
./tools/qstring/Makefile
|
||||
./tools/qstring/utf-8.txt
|
||||
./tools/qstringlist
|
||||
./tools/qstringlist/qstringlist.pro
|
||||
./tools/qstringlist/main.cpp
|
||||
./tools/qstringlist/.gitignore
|
||||
./tools/qstringlist/Makefile
|
||||
./tools/qbytearray
|
||||
./tools/qbytearray/qbytearray.pro
|
||||
./tools/qbytearray/main.cpp
|
||||
./tools/qbytearray/Makefile
|
||||
./tools/containers-associative
|
||||
./tools/containers-associative/containers-associative.pro
|
||||
./tools/containers-associative/main.cpp
|
||||
./tools/containers-associative/Makefile
|
||||
./tools/qrect
|
||||
./tools/qrect/main.cpp
|
||||
./tools/qrect/Makefile
|
||||
./tools/qrect/qrect.pro
|
||||
./tools/Makefile
|
||||
./tools/qhash
|
||||
./tools/qhash/data.txt
|
||||
./tools/qhash/qhash_string.cpp
|
||||
./tools/qhash/.qhash_string.cpp.swp
|
||||
./tools/qhash/qhash.pro
|
||||
./tools/qhash/outofline.cpp
|
||||
./tools/.obj
|
||||
./tools/.obj/debug-shared
|
||||
./Makefile
|
||||
./.obj
|
||||
./.obj/debug-shared
|
||||
./plugin
|
||||
./plugin/plugin.pro
|
||||
./plugin/.pch
|
||||
./plugin/.pch/debug-shared
|
||||
./plugin/Makefile
|
||||
./plugin/.obj
|
||||
./plugin/.obj/debug-shared
|
||||
./plugin/quuid
|
||||
./plugin/quuid/tst_quuid.cpp
|
||||
./plugin/quuid/quuid.pro
|
||||
./plugin/quuid/Makefile
|
||||
./io
|
||||
./io/qtemporaryfile
|
||||
./io/qtemporaryfile/qtemporaryfile.pro
|
||||
./io/qtemporaryfile/main.cpp
|
||||
./io/qtemporaryfile/Makefile
|
||||
./io/qiodevice
|
||||
./io/qiodevice/qiodevice.pro
|
||||
./io/qiodevice/main.cpp
|
||||
./io/qiodevice/Makefile
|
||||
./io/qurl
|
||||
./io/qurl/main.cpp
|
||||
./io/qurl/Makefile
|
||||
./io/qurl/qurl.pro
|
||||
./io/qdir
|
||||
./io/qdir/.pch
|
||||
./io/qdir/.pch/debug-shared
|
||||
./io/qdir/qdir.pro
|
||||
./io/qdir/tree
|
||||
./io/qdir/tree/bench_qdir_tree.qrc
|
||||
./io/qdir/tree/tree.pro
|
||||
./io/qdir/tree/4.6.0-list.txt
|
||||
./io/qdir/tree/Makefile
|
||||
./io/qdir/tree/bench_qdir_tree.cpp
|
||||
./io/qdir/Makefile
|
||||
./io/qdir/.obj
|
||||
./io/qdir/.obj/debug-shared
|
||||
./io/qdir/10000
|
||||
./io/qdir/10000/10000.pro
|
||||
./io/qdir/10000/bench_qdir_10000.cpp
|
||||
./io/qdir/10000/Makefile
|
||||
./io/.pch
|
||||
./io/.pch/debug-shared
|
||||
./io/qfile
|
||||
./io/qfile/qfile.pro
|
||||
./io/qfile/main.cpp
|
||||
./io/qfile/Makefile
|
||||
./io/io.pro
|
||||
./io/qfileinfo
|
||||
./io/qfileinfo/qfileinfo.pro
|
||||
./io/qfileinfo/main.cpp
|
||||
./io/qfileinfo/Makefile
|
||||
./io/qdiriterator
|
||||
./io/qdiriterator/qfilesystemiterator.h
|
||||
./io/qdiriterator/main.cpp
|
||||
./io/qdiriterator/Makefile
|
||||
./io/qdiriterator/qfilesystemiterator.cpp
|
||||
./io/qdiriterator/qdiriterator.pro
|
||||
./io/Makefile
|
||||
./io/.obj
|
||||
./io/.obj/debug-shared
|
||||
./thread
|
||||
./thread/qmutex
|
||||
./thread/qmutex/tst_qmutex.cpp
|
||||
./thread/qmutex/Makefile
|
||||
./thread/qmutex/qmutex.pro
|
||||
./thread/qthreadstorage
|
||||
./thread/qthreadstorage/qthreadstorage.pro
|
||||
./thread/qthreadstorage/Makefile
|
||||
./thread/qthreadstorage/tst_qthreadstorage.cpp
|
||||
./thread/.pch
|
||||
./thread/.pch/debug-shared
|
||||
./thread/Makefile
|
||||
./thread/.obj
|
||||
./thread/.obj/debug-shared
|
||||
./thread/thread.pro
|
90
tests/benchmarks/core/tools/qhash/outofline.cpp
Normal file
90
tests/benchmarks/core/tools/qhash/outofline.cpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtTest module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qhash_string.h"
|
||||
|
||||
static void doHash(const unsigned short *p, uint &h)
|
||||
{
|
||||
#if 1
|
||||
// Copied from static uint hash(const QChar *p, int n).
|
||||
// Possibly not the cheapest way.
|
||||
h = (h << 4) + (*p++);
|
||||
h ^= (h & 0xf0000000) >> 23;
|
||||
h &= 0x0fffffff;
|
||||
|
||||
h = (h << 4) + (*p++);
|
||||
h ^= (h & 0xf0000000) >> 23;
|
||||
h &= 0x0fffffff;
|
||||
|
||||
h = (h << 4) + (*p++);
|
||||
h ^= (h & 0xf0000000) >> 23;
|
||||
h &= 0x0fffffff;
|
||||
|
||||
h = (h << 4) + (*p++);
|
||||
h ^= (h & 0xf0000000) >> 23;
|
||||
h &= 0x0fffffff;
|
||||
#else
|
||||
// Faster, but probably less spread.
|
||||
h ^= *(unsigned int *)p;
|
||||
#endif
|
||||
}
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
uint qHash(const String &str)
|
||||
{
|
||||
const unsigned short *p = (unsigned short *)str.constData();
|
||||
const int s = str.size();
|
||||
switch (s) {
|
||||
case 0: return 0;
|
||||
case 1: return *p;
|
||||
case 2: return *(unsigned int *)p;
|
||||
case 3: return (*(unsigned int *)p) ^ *(p + 2);
|
||||
//case 3: return (*p << 11) + (*(p + 1) << 22) + *(p + 2);
|
||||
}
|
||||
uint h = 0;
|
||||
doHash(p, h);
|
||||
doHash(p + s / 2 - 2, h);
|
||||
doHash(p + s - 4, h);
|
||||
return h;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
131
tests/benchmarks/core/tools/qhash/qhash_string.cpp
Normal file
131
tests/benchmarks/core/tools/qhash/qhash_string.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
This benchmark serves as reality check on the idea that hashing the complete
|
||||
string is a good idea.
|
||||
|
||||
Executive summary: It is not a good idea.
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
********* Start testing of tst_QHash *********
|
||||
Config: Using QTest library 4.8.0, Qt 4.8.0
|
||||
PASS : tst_QHash::initTestCase()
|
||||
RESULT : tst_QHash::qhash_qt4():
|
||||
0.041 msecs per iteration (total: 85, iterations: 2048)
|
||||
PASS : tst_QHash::qhash_qt4()
|
||||
RESULT : tst_QHash::qhash_faster():
|
||||
0.0122 msecs per iteration (total: 100, iterations: 8192)
|
||||
PASS : tst_QHash::qhash_faster()
|
||||
PASS : tst_QHash::cleanupTestCase()
|
||||
Totals: 4 passed, 0 failed, 0 skipped
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
*/
|
||||
|
||||
#include "qhash_string.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <QTest>
|
||||
|
||||
|
||||
class tst_QHash : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void qhash_qt4();
|
||||
void qhash_faster();
|
||||
|
||||
private:
|
||||
QString data();
|
||||
};
|
||||
|
||||
const int N = 1000000;
|
||||
extern double s;
|
||||
|
||||
///////////////////// QHash /////////////////////
|
||||
|
||||
QString tst_QHash::data()
|
||||
{
|
||||
QFile file("data.txt");
|
||||
file.open(QIODevice::ReadOnly);
|
||||
return QString::fromLatin1(file.readAll());
|
||||
}
|
||||
|
||||
void tst_QHash::qhash_qt4()
|
||||
{
|
||||
QStringList items = data().split(QLatin1Char('\n'));
|
||||
QHash<QString, int> hash;
|
||||
|
||||
QBENCHMARK {
|
||||
for (int i = 0, n = items.size(); i != n; ++i) {
|
||||
hash[items.at(i)] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QHash::qhash_faster()
|
||||
{
|
||||
QList<String> items;
|
||||
foreach (const QString &s, data().split(QLatin1Char('\n')))
|
||||
items.append(s);
|
||||
QHash<String, int> hash;
|
||||
|
||||
QBENCHMARK {
|
||||
for (int i = 0, n = items.size(); i != n; ++i) {
|
||||
hash[items.at(i)] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QHash)
|
||||
|
||||
#include "moc_qhash_string.cpp"
|
52
tests/benchmarks/core/tools/qhash/qhash_string.h
Normal file
52
tests/benchmarks/core/tools/qhash/qhash_string.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtTest module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QString>
|
||||
|
||||
struct String : QString
|
||||
{
|
||||
String() {}
|
||||
String(const QString &s) : QString(s) {}
|
||||
};
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
uint qHash(const String &);
|
||||
QT_END_NAMESPACE
|
3
tests/benchmarks/core/tools/qline/CMakeLists.txt
Normal file
3
tests/benchmarks/core/tools/qline/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_qline
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
157
tests/benchmarks/core/tools/qline/main.cpp
Normal file
157
tests/benchmarks/core/tools/qline/main.cpp
Normal file
|
@ -0,0 +1,157 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
// This file contains benchmarks for QLineF functions.
|
||||
|
||||
#include <QDebug>
|
||||
#include <qtest.h>
|
||||
#include <QLine>
|
||||
|
||||
class tst_qline : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void fromPolar();
|
||||
void intersect_data();
|
||||
void intersect();
|
||||
void length();
|
||||
void setLength();
|
||||
void angle();
|
||||
void setAngle();
|
||||
void angleTo();
|
||||
void unitVector();
|
||||
void normalVector();
|
||||
void angle2();
|
||||
};
|
||||
|
||||
void tst_qline::fromPolar()
|
||||
{
|
||||
QBENCHMARK {
|
||||
QLineF::fromPolar(10, 2);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qline::intersect_data()
|
||||
{
|
||||
QTest::addColumn<QLineF>("l1");
|
||||
QTest::addColumn<QLineF>("l2");
|
||||
QTest::newRow("cross") << QLineF(-1,-1,1,1) << QLineF(-1,1,1,-1);
|
||||
QTest::newRow("miss") << QLineF(1,1,2,2) << QLineF(1,11,2,12);
|
||||
}
|
||||
|
||||
void tst_qline::intersect()
|
||||
{
|
||||
QFETCH(QLineF, l1);
|
||||
QFETCH(QLineF, l2);
|
||||
QPointF intersection;
|
||||
QBENCHMARK {
|
||||
l1.intersect(l2, &intersection);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qline::length()
|
||||
{
|
||||
QLineF line(1,2,3,4);
|
||||
QBENCHMARK {
|
||||
line.length();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qline::setLength()
|
||||
{
|
||||
QLineF line(1,2,3,4);
|
||||
QBENCHMARK {
|
||||
line.setLength(5);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qline::angle()
|
||||
{
|
||||
QLineF line(1,2,3,4);
|
||||
QBENCHMARK {
|
||||
line.angle();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qline::setAngle()
|
||||
{
|
||||
QLineF line(1,2,3,4);
|
||||
QBENCHMARK {
|
||||
line.setAngle(1);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qline::angleTo()
|
||||
{
|
||||
QLineF line1(1,2,3,4);
|
||||
QLineF line2(8,7,6,5);
|
||||
QBENCHMARK {
|
||||
line1.angleTo(line2);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qline::unitVector()
|
||||
{
|
||||
QLineF line(1,2,3,4);
|
||||
QBENCHMARK {
|
||||
line.unitVector();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qline::normalVector()
|
||||
{
|
||||
QLineF line(1,2,3,4);
|
||||
QBENCHMARK {
|
||||
line.normalVector();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qline::angle2()
|
||||
{
|
||||
QLineF line1(1,2,3,4);
|
||||
QLineF line2(8,7,6,5);
|
||||
QBENCHMARK {
|
||||
line1.angle(line2);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qline)
|
||||
|
||||
#include "moc_main.cpp"
|
3
tests/benchmarks/core/tools/qlist/CMakeLists.txt
Normal file
3
tests/benchmarks/core/tools/qlist/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_qlist
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
250
tests/benchmarks/core/tools/qlist/main.cpp
Normal file
250
tests/benchmarks/core/tools/qlist/main.cpp
Normal file
|
@ -0,0 +1,250 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QList>
|
||||
#include <QTest>
|
||||
|
||||
static const int N = 1000;
|
||||
|
||||
struct MyBase
|
||||
{
|
||||
MyBase(int i_)
|
||||
: isCopy(false)
|
||||
{
|
||||
++liveCount;
|
||||
|
||||
i = i_;
|
||||
}
|
||||
|
||||
MyBase(const MyBase &other)
|
||||
: isCopy(true)
|
||||
{
|
||||
if (isCopy)
|
||||
++copyCount;
|
||||
++liveCount;
|
||||
|
||||
i = other.i;
|
||||
}
|
||||
|
||||
MyBase &operator=(const MyBase &other)
|
||||
{
|
||||
if (!isCopy) {
|
||||
isCopy = true;
|
||||
++copyCount;
|
||||
} else {
|
||||
++errorCount;
|
||||
}
|
||||
|
||||
i = other.i;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~MyBase()
|
||||
{
|
||||
if (isCopy) {
|
||||
if (!copyCount)
|
||||
++errorCount;
|
||||
else
|
||||
--copyCount;
|
||||
}
|
||||
if (!liveCount)
|
||||
++errorCount;
|
||||
else
|
||||
--liveCount;
|
||||
}
|
||||
|
||||
bool operator==(const MyBase &other) const
|
||||
{ return i == other.i; }
|
||||
|
||||
protected:
|
||||
ushort i;
|
||||
bool isCopy;
|
||||
|
||||
public:
|
||||
static int errorCount;
|
||||
static int liveCount;
|
||||
static int copyCount;
|
||||
};
|
||||
|
||||
int MyBase::errorCount = 0;
|
||||
int MyBase::liveCount = 0;
|
||||
int MyBase::copyCount = 0;
|
||||
|
||||
struct MyPrimitive : public MyBase
|
||||
{
|
||||
MyPrimitive(int i = -1) : MyBase(i)
|
||||
{ ++errorCount; }
|
||||
MyPrimitive(const MyPrimitive &other) : MyBase(other)
|
||||
{ ++errorCount; }
|
||||
~MyPrimitive()
|
||||
{ ++errorCount; }
|
||||
};
|
||||
|
||||
struct MyMovable : public MyBase
|
||||
{
|
||||
MyMovable(int i = -1) : MyBase(i) {}
|
||||
};
|
||||
|
||||
struct MyComplex : public MyBase
|
||||
{
|
||||
MyComplex(int i = -1) : MyBase(i) {}
|
||||
};
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_DECLARE_TYPEINFO(MyPrimitive, Q_PRIMITIVE_TYPE);
|
||||
Q_DECLARE_TYPEINFO(MyMovable, Q_MOVABLE_TYPE);
|
||||
Q_DECLARE_TYPEINFO(MyComplex, Q_COMPLEX_TYPE);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
class tst_QList: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void removeAll_primitive_data();
|
||||
void removeAll_primitive();
|
||||
void removeAll_movable_data();
|
||||
void removeAll_movable();
|
||||
void removeAll_complex_data();
|
||||
void removeAll_complex();
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void removeAll_test(const QList<int> &i10, ushort valueToRemove, int itemsToRemove)
|
||||
{
|
||||
bool isComplex = QTypeInfo<T>::isComplex;
|
||||
|
||||
MyBase::errorCount = 0;
|
||||
MyBase::liveCount = 0;
|
||||
MyBase::copyCount = 0;
|
||||
{
|
||||
QList<T> list;
|
||||
QCOMPARE(MyBase::liveCount, 0);
|
||||
QCOMPARE(MyBase::copyCount, 0);
|
||||
|
||||
for (int i = 0; i < 10 * N; ++i) {
|
||||
T t(i10.at(i % 10));
|
||||
list.append(t);
|
||||
}
|
||||
QCOMPARE(MyBase::liveCount, isComplex ? list.size() : 0);
|
||||
QCOMPARE(MyBase::copyCount, isComplex ? list.size() : 0);
|
||||
|
||||
T t(valueToRemove);
|
||||
QCOMPARE(MyBase::liveCount, isComplex ? list.size() + 1 : 1);
|
||||
QCOMPARE(MyBase::copyCount, isComplex ? list.size() : 0);
|
||||
|
||||
int removedCount;
|
||||
QList<T> l;
|
||||
|
||||
QBENCHMARK {
|
||||
l = list;
|
||||
removedCount = l.removeAll(t);
|
||||
}
|
||||
QCOMPARE(removedCount, itemsToRemove * N);
|
||||
QCOMPARE(l.size() + removedCount, list.size());
|
||||
QVERIFY(!l.contains(valueToRemove));
|
||||
|
||||
QCOMPARE(MyBase::liveCount, isComplex ? l.isDetached() ? list.size() + l.size() + 1 : list.size() + 1 : 1);
|
||||
QCOMPARE(MyBase::copyCount, isComplex ? l.isDetached() ? list.size() + l.size() : list.size() : 0);
|
||||
}
|
||||
if (isComplex)
|
||||
QCOMPARE(MyBase::errorCount, 0);
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(QList<int>);
|
||||
|
||||
void tst_QList::removeAll_primitive_data()
|
||||
{
|
||||
qRegisterMetaType<QList<int> >();
|
||||
|
||||
QTest::addColumn<QList<int> >("i10");
|
||||
QTest::addColumn<int>("valueToRemove");
|
||||
QTest::addColumn<int>("itemsToRemove");
|
||||
|
||||
QTest::newRow("0%") << (QList<int>() << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0) << 5 << 0;
|
||||
QTest::newRow("10%") << (QList<int>() << 0 << 0 << 0 << 0 << 5 << 0 << 0 << 0 << 0 << 0) << 5 << 1;
|
||||
QTest::newRow("90%") << (QList<int>() << 5 << 5 << 5 << 5 << 0 << 5 << 5 << 5 << 5 << 5) << 5 << 9;
|
||||
QTest::newRow("100%") << (QList<int>() << 5 << 5 << 5 << 5 << 5 << 5 << 5 << 5 << 5 << 5) << 5 << 10;
|
||||
}
|
||||
|
||||
void tst_QList::removeAll_primitive()
|
||||
{
|
||||
QFETCH(QList<int>, i10);
|
||||
QFETCH(int, valueToRemove);
|
||||
QFETCH(int, itemsToRemove);
|
||||
|
||||
removeAll_test<MyPrimitive>(i10, valueToRemove, itemsToRemove);
|
||||
}
|
||||
|
||||
void tst_QList::removeAll_movable_data()
|
||||
{
|
||||
removeAll_primitive_data();
|
||||
}
|
||||
|
||||
void tst_QList::removeAll_movable()
|
||||
{
|
||||
QFETCH(QList<int>, i10);
|
||||
QFETCH(int, valueToRemove);
|
||||
QFETCH(int, itemsToRemove);
|
||||
|
||||
removeAll_test<MyMovable>(i10, valueToRemove, itemsToRemove);
|
||||
}
|
||||
|
||||
void tst_QList::removeAll_complex_data()
|
||||
{
|
||||
removeAll_primitive_data();
|
||||
}
|
||||
|
||||
void tst_QList::removeAll_complex()
|
||||
{
|
||||
QFETCH(QList<int>, i10);
|
||||
QFETCH(int, valueToRemove);
|
||||
QFETCH(int, itemsToRemove);
|
||||
|
||||
removeAll_test<MyComplex>(i10, valueToRemove, itemsToRemove);
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_QList)
|
||||
|
||||
#include "moc_main.cpp"
|
3
tests/benchmarks/core/tools/qrect/CMakeLists.txt
Normal file
3
tests/benchmarks/core/tools/qrect/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_qrect
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
329
tests/benchmarks/core/tools/qrect/main.cpp
Normal file
329
tests/benchmarks/core/tools/qrect/main.cpp
Normal file
|
@ -0,0 +1,329 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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 "moc_main.cpp"
|
|
@ -0,0 +1,6 @@
|
|||
katie_test(tst_bench_qregexp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/qregexp.qrc
|
||||
)
|
||||
|
||||
target_link_libraries(tst_bench_qregexp KtScript)
|
595
tests/benchmarks/core/tools/qregexp/main.cpp
Normal file
595
tests/benchmarks/core/tools/qregexp/main.cpp
Normal file
|
@ -0,0 +1,595 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QDebug>
|
||||
#include <QRegExp>
|
||||
#include <QString>
|
||||
#include <QFile>
|
||||
|
||||
#include <qtest.h>
|
||||
#ifdef HAVE_BOOST
|
||||
#include <boost/regex.hpp>
|
||||
#endif
|
||||
|
||||
#include <QtScript>
|
||||
#include "pcre/pcre.h"
|
||||
|
||||
#define ZLIB_VERSION "1.2.3.4"
|
||||
|
||||
class tst_qregexp : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
tst_qregexp();
|
||||
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(); }
|
||||
/*
|
||||
JSC outperforms everything.
|
||||
Boost is less impressive then expected.
|
||||
*/
|
||||
void simpleFind1();
|
||||
void rangeReplace1();
|
||||
void matchReplace1();
|
||||
|
||||
void simpleFind2();
|
||||
void rangeReplace2();
|
||||
void matchReplace2();
|
||||
|
||||
void simpleFindJSC();
|
||||
void rangeReplaceJSC();
|
||||
void matchReplaceJSC();
|
||||
|
||||
#ifdef HAVE_BOOST
|
||||
void simpleFindBoost();
|
||||
void rangeReplaceBoost();
|
||||
void matchReplaceBoost();
|
||||
#endif
|
||||
|
||||
/* those apply an (incorrect) regexp on entire source
|
||||
(this main.cpp). JSC appears to handle this
|
||||
(ab)use case best. QRegExp performs extremly bad.
|
||||
*/
|
||||
void horribleWrongReplace1();
|
||||
void horribleReplace1();
|
||||
void horribleReplace2();
|
||||
void horribleWrongReplace2();
|
||||
void horribleWrongReplaceJSC();
|
||||
void horribleReplaceJSC();
|
||||
#ifdef HAVE_BOOST
|
||||
void horribleWrongReplaceBoost();
|
||||
void horribleReplaceBoost();
|
||||
#endif
|
||||
private:
|
||||
QString str1;
|
||||
QString str2;
|
||||
void escape_data();
|
||||
};
|
||||
|
||||
tst_qregexp::tst_qregexp()
|
||||
:QObject()
|
||||
,str1("We are all happy monkeys")
|
||||
{
|
||||
QFile f(":/main.cpp");
|
||||
f.open(QFile::ReadOnly);
|
||||
str2=f.readAll();
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tst_qregexp::simpleFind1()
|
||||
{
|
||||
int roff;
|
||||
QRegExp rx("happy");
|
||||
rx.setPatternSyntax(QRegExp::RegExp);
|
||||
QBENCHMARK{
|
||||
roff = rx.indexIn(str1);
|
||||
}
|
||||
QCOMPARE(roff, 11);
|
||||
}
|
||||
|
||||
void tst_qregexp::rangeReplace1()
|
||||
{
|
||||
QString r;
|
||||
QRegExp rx("[a-f]");
|
||||
rx.setPatternSyntax(QRegExp::RegExp);
|
||||
QBENCHMARK{
|
||||
r = QString(str1).replace(rx, "-");
|
||||
}
|
||||
QCOMPARE(r, QString("W- -r- -ll h-ppy monk-ys"));
|
||||
}
|
||||
|
||||
void tst_qregexp::matchReplace1()
|
||||
{
|
||||
QString r;
|
||||
QRegExp rx("[^a-f]*([a-f]+)[^a-f]*");
|
||||
rx.setPatternSyntax(QRegExp::RegExp);
|
||||
QBENCHMARK{
|
||||
r = QString(str1).replace(rx, "\\1");
|
||||
}
|
||||
QCOMPARE(r, QString("eaeaae"));
|
||||
}
|
||||
|
||||
void tst_qregexp::horribleWrongReplace1()
|
||||
{
|
||||
QString r;
|
||||
QRegExp rx(".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+)\".*");
|
||||
rx.setPatternSyntax(QRegExp::RegExp);
|
||||
QBENCHMARK{
|
||||
r = QString(str2).replace(rx, "\\1.\\2.\\3");
|
||||
}
|
||||
QCOMPARE(r, str2);
|
||||
}
|
||||
|
||||
void tst_qregexp::horribleReplace1()
|
||||
{
|
||||
QString r;
|
||||
QRegExp rx(".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+).*");
|
||||
rx.setPatternSyntax(QRegExp::RegExp);
|
||||
QBENCHMARK{
|
||||
r = QString(str2).replace(rx, "\\1.\\2.\\3");
|
||||
}
|
||||
QCOMPARE(r, QString("1.2.3"));
|
||||
}
|
||||
|
||||
|
||||
void tst_qregexp::simpleFind2()
|
||||
{
|
||||
int roff;
|
||||
QRegExp rx("happy");
|
||||
rx.setPatternSyntax(QRegExp::RegExp2);
|
||||
QBENCHMARK{
|
||||
roff = rx.indexIn(str1);
|
||||
}
|
||||
QCOMPARE(roff, 11);
|
||||
}
|
||||
|
||||
void tst_qregexp::rangeReplace2()
|
||||
{
|
||||
QString r;
|
||||
QRegExp rx("[a-f]");
|
||||
rx.setPatternSyntax(QRegExp::RegExp2);
|
||||
QBENCHMARK{
|
||||
r = QString(str1).replace(rx, "-");
|
||||
}
|
||||
QCOMPARE(r, QString("W- -r- -ll h-ppy monk-ys"));
|
||||
}
|
||||
|
||||
void tst_qregexp::matchReplace2()
|
||||
{
|
||||
QString r;
|
||||
QRegExp rx("[^a-f]*([a-f]+)[^a-f]*");
|
||||
rx.setPatternSyntax(QRegExp::RegExp2);
|
||||
QBENCHMARK{
|
||||
r = QString(str1).replace(rx, "\\1");
|
||||
}
|
||||
QCOMPARE(r, QString("eaeaae"));
|
||||
}
|
||||
|
||||
void tst_qregexp::horribleWrongReplace2()
|
||||
{
|
||||
QString r;
|
||||
QRegExp rx(".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+)\".*");
|
||||
rx.setPatternSyntax(QRegExp::RegExp2);
|
||||
QBENCHMARK{
|
||||
r = QString(str2).replace(rx, "\\1.\\2.\\3");
|
||||
}
|
||||
QCOMPARE(r, str2);
|
||||
}
|
||||
|
||||
void tst_qregexp::horribleReplace2()
|
||||
{
|
||||
QString r;
|
||||
QRegExp rx(".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+).*");
|
||||
rx.setPatternSyntax(QRegExp::RegExp2);
|
||||
QBENCHMARK{
|
||||
r = QString(str2).replace(rx, "\\1.\\2.\\3");
|
||||
}
|
||||
QCOMPARE(r, QString("1.2.3"));
|
||||
}
|
||||
|
||||
|
||||
void tst_qregexp::simpleFindJSC()
|
||||
{
|
||||
int numr;
|
||||
const char * errmsg=" ";
|
||||
QString rxs("happy");
|
||||
JSRegExp *rx = jsRegExpCompile(rxs.utf16(), rxs.length(), JSRegExpDoNotIgnoreCase, JSRegExpSingleLine, 0, &errmsg);
|
||||
QVERIFY(rx != 0);
|
||||
QString s(str1);
|
||||
int offsetVector[3];
|
||||
QBENCHMARK{
|
||||
numr = jsRegExpExecute(rx, s.utf16(), s.length(), 0, offsetVector, 3);
|
||||
}
|
||||
jsRegExpFree(rx);
|
||||
QCOMPARE(numr, 1);
|
||||
QCOMPARE(offsetVector[0], 11);
|
||||
}
|
||||
|
||||
void tst_qregexp::rangeReplaceJSC()
|
||||
{
|
||||
QScriptValue r;
|
||||
QScriptEngine engine;
|
||||
engine.globalObject().setProperty("s", str1);
|
||||
QScriptValue replaceFunc = engine.evaluate("(function() { return s.replace(/[a-f]/g, '-') } )");
|
||||
QVERIFY(replaceFunc.isFunction());
|
||||
QBENCHMARK{
|
||||
r = replaceFunc.call(QScriptValue());
|
||||
}
|
||||
QCOMPARE(r.toString(), QString("W- -r- -ll h-ppy monk-ys"));
|
||||
}
|
||||
|
||||
void tst_qregexp::matchReplaceJSC()
|
||||
{
|
||||
QScriptValue r;
|
||||
QScriptEngine engine;
|
||||
engine.globalObject().setProperty("s", str1);
|
||||
QScriptValue replaceFunc = engine.evaluate("(function() { return s.replace(/[^a-f]*([a-f]+)[^a-f]*/g, '$1') } )");
|
||||
QVERIFY(replaceFunc.isFunction());
|
||||
QBENCHMARK{
|
||||
r = replaceFunc.call(QScriptValue());
|
||||
}
|
||||
QCOMPARE(r.toString(), QString("eaeaae"));
|
||||
}
|
||||
|
||||
void tst_qregexp::horribleWrongReplaceJSC()
|
||||
{
|
||||
QScriptValue r;
|
||||
QScriptEngine engine;
|
||||
engine.globalObject().setProperty("s", str2);
|
||||
QScriptValue replaceFunc = engine.evaluate("(function() { return s.replace(/.*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+)\".*/gm, '$1.$2.$3') } )");
|
||||
QVERIFY(replaceFunc.isFunction());
|
||||
QBENCHMARK{
|
||||
r = replaceFunc.call(QScriptValue());
|
||||
}
|
||||
QCOMPARE(r.toString(), str2);
|
||||
}
|
||||
|
||||
void tst_qregexp::horribleReplaceJSC()
|
||||
{
|
||||
QScriptValue r;
|
||||
QScriptEngine engine;
|
||||
// the m flag doesnt actually work here; dunno
|
||||
engine.globalObject().setProperty("s", str2.replace('\n', ' '));
|
||||
QScriptValue replaceFunc = engine.evaluate("(function() { return s.replace(/.*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+).*/gm, '$1.$2.$3') } )");
|
||||
QVERIFY(replaceFunc.isFunction());
|
||||
QBENCHMARK{
|
||||
r = replaceFunc.call(QScriptValue());
|
||||
}
|
||||
QCOMPARE(r.toString(), QString("1.2.3"));
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_BOOST
|
||||
void tst_qregexp::simpleFindBoost(){
|
||||
int roff;
|
||||
boost::regex rx ("happy", boost::regex_constants::perl);
|
||||
std::string s = str1.toStdString();
|
||||
std::string::const_iterator start, end;
|
||||
start = s.begin();
|
||||
end = s.end();
|
||||
boost::match_flag_type flags = boost::match_default;
|
||||
QBENCHMARK{
|
||||
boost::match_results<std::string::const_iterator> what;
|
||||
regex_search(start, end, what, rx, flags);
|
||||
roff = (what[0].first)-start;
|
||||
}
|
||||
QCOMPARE(roff, 11);
|
||||
}
|
||||
|
||||
void tst_qregexp::rangeReplaceBoost()
|
||||
{
|
||||
boost::regex pattern ("[a-f]", boost::regex_constants::perl);
|
||||
std::string s = str1.toStdString();
|
||||
std::string r;
|
||||
QBENCHMARK{
|
||||
r = boost::regex_replace (s, pattern, "-");
|
||||
}
|
||||
QCOMPARE(r, std::string("W- -r- -ll h-ppy monk-ys"));
|
||||
}
|
||||
|
||||
void tst_qregexp::matchReplaceBoost()
|
||||
{
|
||||
boost::regex pattern ("[^a-f]*([a-f]+)[^a-f]*",boost::regex_constants::perl);
|
||||
std::string s = str1.toStdString();
|
||||
std::string r;
|
||||
QBENCHMARK{
|
||||
r = boost::regex_replace (s, pattern, "$1");
|
||||
}
|
||||
QCOMPARE(r, std::string("eaeaae"));
|
||||
}
|
||||
|
||||
void tst_qregexp::horribleWrongReplaceBoost()
|
||||
{
|
||||
boost::regex pattern (".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+)\".*", boost::regex_constants::perl);
|
||||
std::string s = str2.toStdString();
|
||||
std::string r;
|
||||
QBENCHMARK{
|
||||
r = boost::regex_replace (s, pattern, "$1.$2.$3");
|
||||
}
|
||||
QCOMPARE(r, s);
|
||||
}
|
||||
|
||||
void tst_qregexp::horribleReplaceBoost()
|
||||
{
|
||||
boost::regex pattern (".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+).*", boost::regex_constants::perl);
|
||||
std::string s = str2.toStdString();
|
||||
std::string r;
|
||||
QBENCHMARK{
|
||||
r = boost::regex_replace (s, pattern, "$1.$2.$3");
|
||||
}
|
||||
QCOMPARE(r, std::string("1.2.3"));
|
||||
}
|
||||
#endif //HAVE_BOOST
|
||||
|
||||
QTEST_MAIN(tst_qregexp)
|
||||
|
||||
#include "moc_main.cpp"
|
||||
#include "qrc_qregexp.cpp"
|
7
tests/benchmarks/core/tools/qregexp/qregexp.pro
Normal file
7
tests/benchmarks/core/tools/qregexp/qregexp.pro
Normal file
|
@ -0,0 +1,7 @@
|
|||
include( $${QT_SOURCE_TREE}/src/3rdparty/webkit/Source/JavaScriptCore/JavaScriptCore.pri )
|
||||
|
||||
exists( /usr/include/boost/regex.hpp ){
|
||||
DEFINES+=HAVE_BOOST
|
||||
LIBS+=-lboost_regex
|
||||
}
|
||||
|
6
tests/benchmarks/core/tools/qregexp/qregexp.qrc
Normal file
6
tests/benchmarks/core/tools/qregexp/qregexp.qrc
Normal file
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>main.cpp</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
8
tests/benchmarks/core/tools/qstring/CMakeLists.txt
Normal file
8
tests/benchmarks/core/tools/qstring/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
if(NOT KATIE_COMPILER STREQUAL "gcc")
|
||||
katie_test(tst_bench_qstring
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/data.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fromlatin1.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fromutf8.cpp
|
||||
)
|
||||
endif()
|
1281
tests/benchmarks/core/tools/qstring/data.cpp
Normal file
1281
tests/benchmarks/core/tools/qstring/data.cpp
Normal file
File diff suppressed because it is too large
Load diff
70
tests/benchmarks/core/tools/qstring/data.h
Normal file
70
tests/benchmarks/core/tools/qstring/data.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef DATA_H
|
||||
#define DATA_H
|
||||
|
||||
#include <qglobal.h>
|
||||
|
||||
struct StringCollection
|
||||
{
|
||||
int len;
|
||||
int offset1, offset2;
|
||||
ushort align1, align2;
|
||||
};
|
||||
|
||||
extern const ushort stringCollectionData[];
|
||||
extern const StringCollection stringCollection[];
|
||||
extern const int stringCollectionCount;
|
||||
|
||||
struct StringData
|
||||
{
|
||||
const int *entries;
|
||||
union {
|
||||
const char *charData;
|
||||
const ushort *ushortData;
|
||||
};
|
||||
|
||||
int entryCount;
|
||||
int maxLength;
|
||||
};
|
||||
|
||||
#endif // DATA_H
|
43065
tests/benchmarks/core/tools/qstring/fromlatin1.cpp
Normal file
43065
tests/benchmarks/core/tools/qstring/fromlatin1.cpp
Normal file
File diff suppressed because it is too large
Load diff
28567
tests/benchmarks/core/tools/qstring/fromutf8.cpp
Normal file
28567
tests/benchmarks/core/tools/qstring/fromutf8.cpp
Normal file
File diff suppressed because it is too large
Load diff
198
tests/benchmarks/core/tools/qstring/generatelist.pl
Normal file
198
tests/benchmarks/core/tools/qstring/generatelist.pl
Normal file
|
@ -0,0 +1,198 @@
|
|||
#!/usr/bin/perl
|
||||
## Copyright (C) 2015 The Qt Company Ltd.
|
||||
## Contact: http://www.qt.io/licensing/
|
||||
##
|
||||
## This file is part of the QtCore module of the Qt Toolkit.
|
||||
##
|
||||
## $QT_BEGIN_LICENSE:LGPL$
|
||||
## Commercial License Usage
|
||||
## Licensees holding valid commercial Qt licenses may use this file in
|
||||
## accordance with the commercial license agreement provided with the
|
||||
## Software or, alternatively, in accordance with the terms contained in
|
||||
## a written agreement between you and The Qt Company. For licensing terms
|
||||
## and conditions see http://www.qt.io/terms-conditions. For further
|
||||
## information use the contact form at http://www.qt.io/contact-us.
|
||||
##
|
||||
## 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 or version 3 as published by the Free
|
||||
## Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
## LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
## following information to ensure the GNU Lesser General Public License
|
||||
## requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
##
|
||||
## As a special exception, The Qt Company gives you certain additional
|
||||
## rights. These rights are described in The Qt Company LGPL Exception
|
||||
## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
##
|
||||
## GNU General Public License Usage
|
||||
## Alternatively, this file may be used under the terms of the GNU
|
||||
## General Public License version 3.0 as published by the Free Software
|
||||
## Foundation and appearing in the file LICENSE.GPL included in the
|
||||
## packaging of this file. Please review the following information to
|
||||
## ensure the GNU General Public License version 3.0 requirements will be
|
||||
## met: http://www.gnu.org/copyleft/gpl.html.
|
||||
##
|
||||
## $QT_END_LICENSE$
|
||||
#
|
||||
# Parses a file (passed as argument) that contains a dump of pairs of
|
||||
# strings and generates C source code including said data.
|
||||
#
|
||||
# The format of the file is:
|
||||
# LEN = <len> <keyword> <align1> <align2>\n<data1><data2>\n
|
||||
# where:
|
||||
# LEN the literal string "LEN"
|
||||
# <len> the length of the data, in 16-bit words
|
||||
# <keyword> the literal string "SAME" or "DIFF"
|
||||
# <align1> the alignment or pointer value of the first data
|
||||
# <align2> the alignment or pointer value of the second data
|
||||
# <data1> the first data
|
||||
# <data2> the second data
|
||||
# \n newline
|
||||
#
|
||||
# The code to write this data would be:
|
||||
# fprintf(out, "LEN = %d %s %d %d\n", len,
|
||||
# (p1 == p2) ? "SAME" : "DIFF",
|
||||
# uint(quintptr(p1)) & 0xfff, uint(quintptr(p2)) & 0xfff);
|
||||
# fwrite(p1, 2, len, out);
|
||||
# fwrite(p2, 2, len, out);
|
||||
# fwrite("\n", 1, 1, out);
|
||||
|
||||
sub printUshortArray($$$) {
|
||||
$str = $_[0];
|
||||
$align = $_[1] & 0x1f;
|
||||
$offset = $_[2];
|
||||
|
||||
die if ($align & 1) != 0;
|
||||
$align /= 2;
|
||||
|
||||
$len = (length $str) / 2;
|
||||
$headpadding = $align & 0x7;
|
||||
$tailpadding = 8 - (($len + $headpadding) & 0x7);
|
||||
$multiplecachelines = ($align + $len) > 0x20;
|
||||
|
||||
if ($multiplecachelines) {
|
||||
# if this string crosses into a new cacheline, then
|
||||
# replicate the result
|
||||
$headpadding |= ($offset & ~0x1f);
|
||||
$headpadding += 0x20
|
||||
if ($headpadding < $offset);
|
||||
$headpadding -= $offset;
|
||||
++$cachelinecrosses;
|
||||
}
|
||||
for $i (1..$headpadding) {
|
||||
print 65536-$i,",";
|
||||
}
|
||||
print "\n " if ($headpadding > 0);
|
||||
print " " if ($headpadding == 0);
|
||||
|
||||
for ($i = 0; $i < $len * 2; $i += 2) {
|
||||
print " ", ord(substr($str, $i, 1)) +
|
||||
ord(substr($str, $i + 1, 1)) * 256,
|
||||
",";
|
||||
}
|
||||
print "\n " if ($tailpadding > 0);
|
||||
|
||||
for $i (1..$tailpadding) {
|
||||
print 65536-$i, ",";
|
||||
}
|
||||
print " // ", $offset + $headpadding + $len + $tailpadding;
|
||||
print "+" if $multiplecachelines;
|
||||
|
||||
return ($offset + $headpadding, $offset + $headpadding + $len + $tailpadding);
|
||||
}
|
||||
|
||||
print "// This is a generated file - DO NOT EDIT\n\n";
|
||||
|
||||
print "#include \"data.h\"\n\n";
|
||||
|
||||
print "const ushort stringCollectionData[] __attribute__((aligned(64))) = {\n";
|
||||
$count = 0;
|
||||
$offset = 0;
|
||||
$totalsize = 0;
|
||||
$maxlen = 0;
|
||||
$cachelinecrosses = 0;
|
||||
|
||||
open IN, "<" . $ARGV[0];
|
||||
while (1) {
|
||||
$line = readline(*IN);
|
||||
last unless defined($line);
|
||||
$line =~ /LEN = (\d+) (\w+) (\d+) (\d+)/;
|
||||
$len = $1;
|
||||
$data[$count]->{len} = $len;
|
||||
$sameptr = $2;
|
||||
$data[$count]->{align1} = $3 - 0;
|
||||
$data[$count]->{align2} = $4 - 0;
|
||||
|
||||
# statistics
|
||||
$alignhistogram{$3 & 0xf}++;
|
||||
$alignhistogram{$4 & 0xf}++;
|
||||
$samealignments{$3 & 0xf}++ if ($3 & 0xf) == ($4 & 0xf);
|
||||
|
||||
read IN, $a, $len * 2;
|
||||
read IN, $b, $len * 2;
|
||||
|
||||
<IN>; # Eat the newline
|
||||
|
||||
if ($len == 0) {
|
||||
$data[$count]->{offset1} = $offset;
|
||||
$data[$count]->{offset2} = $data[$count]->{offset1};
|
||||
++$data[$count]->{offset2} if ($sameptr eq "DIFF");
|
||||
} else {
|
||||
print " // #$count\n";
|
||||
print " ";
|
||||
($data[$count]->{offset1}, $offset) =
|
||||
printUshortArray($a, $data[$count]->{align1}, $offset);
|
||||
print "\n ";
|
||||
die if ($offset & 0x7) != 0;
|
||||
|
||||
if ($sameptr eq "DIFF") {
|
||||
($data[$count]->{offset2}, $offset) =
|
||||
printUshortArray($b, $data[$count]->{align2}, $offset);
|
||||
print "\n\n";
|
||||
} else {
|
||||
$data[$count]->{offset2} = $data[$count]->{offset1};
|
||||
print "\n\n";
|
||||
}
|
||||
}
|
||||
++$count;
|
||||
|
||||
$totalsize += $len;
|
||||
$maxlen = $len if $len > $maxlen;
|
||||
}
|
||||
print "};\n";
|
||||
close IN;
|
||||
|
||||
print "const struct StringCollection stringCollection[] = {\n";
|
||||
for $i (0..$count-1) {
|
||||
print " {",
|
||||
$data[$i]->{len}, ", ",
|
||||
$data[$i]->{offset1}, ", ",
|
||||
$data[$i]->{offset2}, ", ",
|
||||
$data[$i]->{align1}, ", ",
|
||||
$data[$i]->{align2},
|
||||
"}, // #$i\n";
|
||||
next if $data[$i]->{len} == 0;
|
||||
die if (($data[$i]->{offset1} & 0x7) != ($data[$i]->{align1} & 0xf)/2);
|
||||
die if (($data[$i]->{offset2} & 0x7) != ($data[$i]->{align2} & 0xf)/2);
|
||||
}
|
||||
print "};\n";
|
||||
|
||||
print "const int stringCollectionCount = $count;\n";
|
||||
print "const int stringCollectionMaxLen = $maxlen;\n";
|
||||
printf "// average comparison length: %.4f\n", ($totalsize * 1.0 / $count);
|
||||
printf "// cache-line crosses: %d (%.1f%%)\n",
|
||||
$cachelinecrosses, ($cachelinecrosses * 100.0 / $count / 2);
|
||||
|
||||
print "// alignment histogram:\n";
|
||||
for $key (sort { $a <=> $b } keys(%alignhistogram)) {
|
||||
$value = $alignhistogram{$key};
|
||||
$samealigned = $samealignments{$key};
|
||||
printf "// 0xXXX%x = %d (%.1f%%) strings, %d (%.1f%%) of which same-aligned\n",
|
||||
$key, $value, $value * 100.0 / ($count*2),
|
||||
$samealigned, $samealigned * 100.0 / $value;
|
||||
$samealignedtotal += $samealigned;
|
||||
}
|
||||
printf "// total = %d (100%) strings, %d (%.1f%%) of which same-aligned\n",
|
||||
$count * 2, $samealignedtotal, $samealignedtotal * 100 / $count / 2;
|
208
tests/benchmarks/core/tools/qstring/generatelist_char.pl
Normal file
208
tests/benchmarks/core/tools/qstring/generatelist_char.pl
Normal file
|
@ -0,0 +1,208 @@
|
|||
#!/usr/bin/perl
|
||||
# -*- mode: utf-8; tabs: nil -*-
|
||||
## Copyright (C) 2015 The Qt Company Ltd.
|
||||
## Contact: http://www.qt.io/licensing/
|
||||
##
|
||||
## This file is part of the QtCore module of the Qt Toolkit.
|
||||
##
|
||||
## $QT_BEGIN_LICENSE:LGPL$
|
||||
## Commercial License Usage
|
||||
## Licensees holding valid commercial Qt licenses may use this file in
|
||||
## accordance with the commercial license agreement provided with the
|
||||
## Software or, alternatively, in accordance with the terms contained in
|
||||
## a written agreement between you and The Qt Company. For licensing terms
|
||||
## and conditions see http://www.qt.io/terms-conditions. For further
|
||||
## information use the contact form at http://www.qt.io/contact-us.
|
||||
##
|
||||
## 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 or version 3 as published by the Free
|
||||
## Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
## LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
## following information to ensure the GNU Lesser General Public License
|
||||
## requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
##
|
||||
## As a special exception, The Qt Company gives you certain additional
|
||||
## rights. These rights are described in The Qt Company LGPL Exception
|
||||
## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
##
|
||||
## GNU General Public License Usage
|
||||
## Alternatively, this file may be used under the terms of the GNU
|
||||
## General Public License version 3.0 as published by the Free Software
|
||||
## Foundation and appearing in the file LICENSE.GPL included in the
|
||||
## packaging of this file. Please review the following information to
|
||||
## ensure the GNU General Public License version 3.0 requirements will be
|
||||
## met: http://www.gnu.org/copyleft/gpl.html.
|
||||
##
|
||||
## $QT_END_LICENSE$
|
||||
#
|
||||
# Parses a file (passed as argument) that contains a dump of pairs of
|
||||
# strings and generates C source code including said data.
|
||||
#
|
||||
# The format of the file is:
|
||||
# LEN = <len> <keyword> <align1> <align2>\n<data1><data2>\n
|
||||
# where:
|
||||
# LEN the literal string "LEN"
|
||||
# <len> the length of the data, in 16-bit words
|
||||
# <keyword> the literal string "SAME" or "DIFF"
|
||||
# <align1> the alignment or pointer value of the first data
|
||||
# <align2> the alignment or pointer value of the second data
|
||||
# <data1> the first data
|
||||
# <data2> the second data
|
||||
# \n newline
|
||||
#
|
||||
# The code to write this data would be:
|
||||
# fprintf(out, "LEN = %d %s %d %d\n", len,
|
||||
# (p1 == p2) ? "SAME" : "DIFF",
|
||||
# uint(quintptr(p1)) & 0xfff, uint(quintptr(p2)) & 0xfff);
|
||||
# fwrite(p1, 2, len, out);
|
||||
# fwrite(p2, 2, len, out);
|
||||
# fwrite("\n", 1, 1, out);
|
||||
|
||||
sub printCharArray($$$) {
|
||||
$str = $_[0];
|
||||
$align = $_[1] & 0x3f;
|
||||
$offset = $_[2];
|
||||
|
||||
$headpadding = $align & 0xf;
|
||||
$tailpadding = 16 - (($len + $headpadding) & 0xf);
|
||||
$multiplecachelines = ($align + $len) > 0x40;
|
||||
|
||||
if ($multiplecachelines) {
|
||||
# if this string crosses into a new cacheline, then
|
||||
# replicate the result
|
||||
$headpadding |= ($offset & ~0x3f);
|
||||
$headpadding += 0x40
|
||||
if ($headpadding < $offset);
|
||||
$headpadding -= $offset;
|
||||
++$cachelinecrosses;
|
||||
}
|
||||
|
||||
if ($headpadding > 0) {
|
||||
print " \"";
|
||||
for $i (1..$headpadding) {
|
||||
printf "\\%o", 256-$i;
|
||||
}
|
||||
print "\"\n";
|
||||
}
|
||||
|
||||
print " \"";
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$c = substr($str, $i, 1);
|
||||
if (ord($c) < 0x20 || ord($c) > 0x7f || $c eq '"' || $c eq '\\') {
|
||||
printf "\\%o\"\"", ord($c);
|
||||
} else {
|
||||
print $c;
|
||||
}
|
||||
}
|
||||
|
||||
if ($tailpadding > 0) {
|
||||
print "\"\n \"";
|
||||
for $i (1..$tailpadding) {
|
||||
printf "\\%o", 256-$i;
|
||||
}
|
||||
}
|
||||
print "\" // ", $offset + $headpadding + $len + $tailpadding;
|
||||
print "+" if $multiplecachelines;
|
||||
print "\n";
|
||||
|
||||
return ($offset + $headpadding, $offset + $headpadding + $len + $tailpadding);
|
||||
}
|
||||
|
||||
print "// This is a generated file - DO NOT EDIT\n\n";
|
||||
|
||||
print "#include \"data.h\"\n\n";
|
||||
|
||||
$varname = shift @ARGV;
|
||||
print "static const char charData[] __attribute__((aligned(64))) = {\n";
|
||||
$count = 0;
|
||||
$offset = 0;
|
||||
$totalsize = 0;
|
||||
$maxlen = 0;
|
||||
$cachelinecrosses = 0;
|
||||
|
||||
open IN, "<" . $ARGV[0];
|
||||
while (1) {
|
||||
$line = readline(*IN);
|
||||
last unless defined($line);
|
||||
$line =~ /LEN = (\d+) (\w+) (\d+) (\d+)/;
|
||||
$len = $1;
|
||||
$data[$count]->{len} = $len;
|
||||
$sameptr = $2;
|
||||
$data[$count]->{align1} = $3 - 0;
|
||||
$data[$count]->{align2} = $4 - 0;
|
||||
|
||||
# statistics
|
||||
$alignhistogram{$3 & 0xf}++;
|
||||
$alignhistogram{$4 & 0xf}++;
|
||||
$samealignments{$3 & 0xf}++ if ($3 & 0xf) == ($4 & 0xf);
|
||||
|
||||
read IN, $a, $len;
|
||||
read IN, $b, $len;
|
||||
|
||||
<IN>; # Eat the newline
|
||||
|
||||
if ($len == 0) {
|
||||
$data[$count]->{offset1} = $offset;
|
||||
$data[$count]->{offset2} = $data[$count]->{offset1};
|
||||
++$data[$count]->{offset2} if ($sameptr eq "DIFF");
|
||||
} else {
|
||||
print " // #$count\n";
|
||||
($data[$count]->{offset1}, $offset) =
|
||||
printCharArray($a, $data[$count]->{align1}, $offset);
|
||||
die if ($offset & 0xf) != 0;
|
||||
|
||||
if ($sameptr eq "DIFF") {
|
||||
($data[$count]->{offset2}, $offset) =
|
||||
printCharArray($b, $data[$count]->{align2}, $offset);
|
||||
} else {
|
||||
$data[$count]->{offset2} = $data[$count]->{offset1};
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
++$count;
|
||||
|
||||
$totalsize += $len;
|
||||
$maxlen = $len if $len > $maxlen;
|
||||
}
|
||||
print "};\n";
|
||||
close IN;
|
||||
|
||||
print "static const int intData[] = {\n";
|
||||
for $i (0..$count-1) {
|
||||
print " ",
|
||||
$data[$i]->{len}, ", ",
|
||||
$data[$i]->{offset1}, ", ",
|
||||
$data[$i]->{offset2}, ", ",
|
||||
$data[$i]->{align1}, ", ",
|
||||
$data[$i]->{align2},
|
||||
", // #$i\n";
|
||||
next if $data[$i]->{len} == 0;
|
||||
die if (($data[$i]->{offset1} & 0xf) != ($data[$i]->{align1} & 0xf));
|
||||
die if (($data[$i]->{offset2} & 0xf) != ($data[$i]->{align2} & 0xf));
|
||||
}
|
||||
print "};\n\n";
|
||||
|
||||
print "struct StringData $varname = {\n" .
|
||||
" intData,\n" .
|
||||
" { charData },\n" .
|
||||
" $count, /* entryCount */\n" .
|
||||
" $maxlen /* maxLength */\n" .
|
||||
"};\n\n";
|
||||
|
||||
printf "// average comparison length: %.4f\n", ($totalsize * 1.0 / $count);
|
||||
printf "// cache-line crosses: %d (%.1f%%)\n",
|
||||
$cachelinecrosses, ($cachelinecrosses * 100.0 / $count / 2);
|
||||
|
||||
print "// alignment histogram:\n";
|
||||
for $key (sort { $a <=> $b } keys(%alignhistogram)) {
|
||||
$value = $alignhistogram{$key};
|
||||
$samealigned = $samealignments{$key};
|
||||
printf "// 0xXXX%x = %d (%.1f%%) strings, %d (%.1f%%) of which same-aligned\n",
|
||||
$key, $value, $value * 100.0 / ($count*2),
|
||||
$samealigned, $samealigned * 100.0 / $value;
|
||||
$samealignedtotal += $samealigned;
|
||||
}
|
||||
printf "// total = %d (100%) strings, %d (%.1f%%) of which same-aligned\n",
|
||||
$count * 2, $samealignedtotal, $samealignedtotal * 100 / $count / 2;
|
2700
tests/benchmarks/core/tools/qstring/main.cpp
Normal file
2700
tests/benchmarks/core/tools/qstring/main.cpp
Normal file
File diff suppressed because it is too large
Load diff
4
tests/benchmarks/core/tools/qstring/qstring.pro
Normal file
4
tests/benchmarks/core/tools/qstring/qstring.pro
Normal file
|
@ -0,0 +1,4 @@
|
|||
sse4:QMAKE_CXXFLAGS += -msse4
|
||||
else:ssse3:QMAKE_FLAGS += -mssse3
|
||||
else:sse2:QMAKE_CXXFLAGS += -msse2
|
||||
neon:QMAKE_CXXFLAGS += -mfpu=neon
|
72
tests/benchmarks/core/tools/qstring/utf-8.txt
Normal file
72
tests/benchmarks/core/tools/qstring/utf-8.txt
Normal file
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_qstringbuilder
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
433
tests/benchmarks/core/tools/qstringbuilder/main.cpp
Normal file
433
tests/benchmarks/core/tools/qstringbuilder/main.cpp
Normal file
|
@ -0,0 +1,433 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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;
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_qstringbuilder)
|
||||
|
||||
#include "moc_main.cpp"
|
1
tests/benchmarks/core/tools/qstringlist/.gitignore
vendored
Normal file
1
tests/benchmarks/core/tools/qstringlist/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
tst_qstringlist
|
3
tests/benchmarks/core/tools/qstringlist/CMakeLists.txt
Normal file
3
tests/benchmarks/core/tools/qstringlist/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
katie_test(tst_bench_qstringlist
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
218
tests/benchmarks/core/tools/qstringlist/main.cpp
Normal file
218
tests/benchmarks/core/tools/qstringlist/main.cpp
Normal file
|
@ -0,0 +1,218 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $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
|
||||
{
|
||||
#ifndef QT_NO_STL
|
||||
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))
|
||||
;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QStringList::split_stdvector_stdwstring() const
|
||||
{
|
||||
#ifndef QT_NO_STL
|
||||
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))
|
||||
;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
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 "moc_main.cpp"
|
4
tests/benchmarks/core/tools/qvector/CMakeLists.txt
Normal file
4
tests/benchmarks/core/tools/qvector/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
katie_test(tst_vector
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/outofline.cpp
|
||||
)
|
390
tests/benchmarks/core/tools/qvector/main.cpp
Normal file
390
tests/benchmarks/core/tools/qvector/main.cpp
Normal file
|
@ -0,0 +1,390 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QVector>
|
||||
#include <QDebug>
|
||||
#include <QtTest>
|
||||
|
||||
#include "qrawvector.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
|
||||
Code generated by g++ 4.3.3. The lines marked with '!' are the ones that get
|
||||
executed inside the loop. Using the external 's' causes some load making the
|
||||
loop resembling a 'simple inner loop' in 'real' applications.
|
||||
|
||||
|
||||
qvector_mutable_read_access:
|
||||
|
||||
.L166:
|
||||
! movl -16(%ebp), %edx
|
||||
! movl (%edx), %eax
|
||||
! subl $1, %eax
|
||||
! je .L165
|
||||
movl 4(%edx), %eax
|
||||
movl %eax, 8(%esp)
|
||||
movl 8(%edx), %eax
|
||||
movl %esi, (%esp)
|
||||
movl %eax, 4(%esp)
|
||||
call _ZN4myns7QVectorIdE7reallocEii
|
||||
.L165:
|
||||
! movl -16(%ebp), %eax
|
||||
! fldl s
|
||||
! faddl 16(%eax,%ebx,8)
|
||||
! addl $1, %ebx
|
||||
! cmpl $10000, %ebx
|
||||
! fstpl s
|
||||
! jne .L166
|
||||
|
||||
|
||||
qvector_const_read_access:
|
||||
|
||||
movl -16(%ebp), %edx
|
||||
xorl %eax, %eax
|
||||
.L183:
|
||||
! fldl s
|
||||
! faddl 16(%edx,%eax,8)
|
||||
! addl $1, %eax
|
||||
! cmpl $10000, %eax
|
||||
! fstpl s
|
||||
! jne .L183
|
||||
|
||||
|
||||
stdvector_const_read_access and stdvector_mutable_read_access and
|
||||
qrawvector_const_read_access and qrawvector_mutable_read_access:
|
||||
|
||||
xorl %eax, %eax
|
||||
.L64:
|
||||
! fldl s
|
||||
! faddl (%ebx,%eax,8)
|
||||
! addl $1, %eax
|
||||
! cmpl $10000, %eax
|
||||
! fstpl s
|
||||
! jne .L64
|
||||
|
||||
|
||||
|
||||
Behaviour varies with small modifications, but total is more or
|
||||
less stable:
|
||||
|
||||
qrawvector_mutable_read_access, using size() instead of N:
|
||||
|
||||
.L145:
|
||||
! faddl (%edx,%eax,8)
|
||||
! addl $1, %eax
|
||||
! cmpl %ecx, %eax
|
||||
! fstl s
|
||||
! jne .L145
|
||||
! fstp %st(0)
|
||||
|
||||
|
||||
qrawvector_mutable_read_access, counting backward:
|
||||
|
||||
.L145:
|
||||
! faddl (%edx,%eax,8)
|
||||
! subl $1, %eax
|
||||
! cmpl $-1, %eax
|
||||
! fstl s
|
||||
! jne .L145
|
||||
|
||||
|
||||
qrawvector_mutable_read_access, counting backward, using size():
|
||||
|
||||
.L146:
|
||||
! faddl (%edx)
|
||||
! addl $1, %eax
|
||||
! subl $8, %edx
|
||||
! cmpl %ecx, %eax
|
||||
! fstl s
|
||||
! jne .L146
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
time ./tst_vector qvector_const_read_access
|
||||
real 0m12.912s
|
||||
user 0m12.401s
|
||||
sys 0m0.016s
|
||||
|
||||
time ./tst_vector qvector_mutable_read_access
|
||||
real 0m38.566s
|
||||
user 0m36.754s
|
||||
sys 0m0.008s
|
||||
|
||||
|
||||
time ./tst_vector stdvector_mutable_read_access
|
||||
real 0m12.736s
|
||||
user 0m12.665s
|
||||
sys 0m0.004s
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
time ./tst_vector qvector_fill_and_return
|
||||
real 0m28.778s
|
||||
user 0m28.522s
|
||||
sys 0m0.012s
|
||||
|
||||
time ./tst_vector stdvector_fill_and_return
|
||||
real 0m26.675s
|
||||
user 0m26.558s
|
||||
sys 0m0.012s
|
||||
|
||||
time ./tst_vector qrawvector_fill_and_return
|
||||
real 0m23.370s
|
||||
user 0m23.269s
|
||||
sys 0m0.008s
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define TEST_RETURN 1
|
||||
|
||||
// For some reason, both 'plain' and '-callgrind' create strange results
|
||||
// (like varying instruction count for the same assembly code)
|
||||
// So replace it by a plain loop and measure wall clock time.
|
||||
//#undef QBENCHMARK
|
||||
//#define QBENCHMARK for (int j = 0; j != 10000; ++j)
|
||||
|
||||
class tst_QVector: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void calibration();
|
||||
|
||||
// Pure Qt solution
|
||||
void qvector_separator() { qWarning() << "QVector results: "; }
|
||||
void qvector_const_read_access();
|
||||
void qvector_mutable_read_access();
|
||||
#ifdef TEST_RETURN
|
||||
void qvector_fill_and_return();
|
||||
#endif
|
||||
|
||||
// Purre Standard solution
|
||||
void stdvector() { qWarning() << "std::vector results: "; }
|
||||
void stdvector_const_read_access();
|
||||
void stdvector_mutable_read_access();
|
||||
#ifdef TEST_RETURN
|
||||
void stdvector_fill_and_return();
|
||||
#endif
|
||||
|
||||
// Build using std, pass as QVector
|
||||
void mixedvector() { qWarning() << "mixed results: "; }
|
||||
#ifdef TEST_RETURN
|
||||
void mixedvector_fill_and_return();
|
||||
#endif
|
||||
|
||||
// Alternative implementation
|
||||
void qrawvector_separator() { qWarning() << "QRawVector results: "; }
|
||||
void qrawvector_const_read_access();
|
||||
void qrawvector_mutable_read_access();
|
||||
#ifdef TEST_RETURN
|
||||
void qrawvector_fill_and_return();
|
||||
#endif
|
||||
};
|
||||
|
||||
const int N = 1000000;
|
||||
extern double s;
|
||||
|
||||
void tst_QVector::calibration()
|
||||
{
|
||||
QVector<double> v(N);
|
||||
for (int i = 0; i != N; ++i)
|
||||
v[i] = i;
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i != N; ++i)
|
||||
s += i;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////// QVector /////////////////////
|
||||
|
||||
void tst_QVector::qvector_const_read_access()
|
||||
{
|
||||
QVector<double> v(N);
|
||||
for (int i = 0; i != N; ++i)
|
||||
v[i] = i;
|
||||
|
||||
const QVector<double> &vc = v;
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i != N; ++i)
|
||||
s += vc[i];
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QVector::qvector_mutable_read_access()
|
||||
{
|
||||
QVector<double> v(N);
|
||||
for (int i = 0; i != N; ++i)
|
||||
v[i] = i;
|
||||
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i != N; ++i)
|
||||
s += v[i];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST_RETURN
|
||||
extern QVector<double> qvector_fill_and_return_helper();
|
||||
|
||||
void tst_QVector::qvector_fill_and_return()
|
||||
{
|
||||
QBENCHMARK {
|
||||
QVector<double> v = qvector_fill_and_return_helper();
|
||||
s += v[1];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////// QRawVector /////////////////////
|
||||
|
||||
void tst_QVector::qrawvector_const_read_access()
|
||||
{
|
||||
QRawVector<double> v(N);
|
||||
for (int i = 0; i != N; ++i)
|
||||
v[i] = i;
|
||||
|
||||
const QRawVector<double> &vc = v;
|
||||
QBENCHMARK {
|
||||
for (int i = vc.size(); --i >= 0;)
|
||||
s += vc[i];
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QVector::qrawvector_mutable_read_access()
|
||||
{
|
||||
QRawVector<double> v(N);
|
||||
for (int i = 0; i != N; ++i)
|
||||
v[i] = i;
|
||||
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i != N; ++i)
|
||||
s += v[i];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST_RETURN
|
||||
extern QVector<double> qrawvector_fill_and_return_helper();
|
||||
|
||||
void tst_QVector::qrawvector_fill_and_return()
|
||||
{
|
||||
QBENCHMARK {
|
||||
QVector<double> v = qrawvector_fill_and_return_helper();
|
||||
s += v[1];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////// std::vector /////////////////////
|
||||
|
||||
void tst_QVector::stdvector_const_read_access()
|
||||
{
|
||||
std::vector<double> v(N);
|
||||
for (int i = 0; i != N; ++i)
|
||||
v[i] = i;
|
||||
|
||||
const std::vector<double> &vc = v;
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i != N; ++i)
|
||||
s += vc[i];
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QVector::stdvector_mutable_read_access()
|
||||
{
|
||||
std::vector<double> v(N);
|
||||
for (int i = 0; i != N; ++i)
|
||||
v[i] = i;
|
||||
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i != N; ++i)
|
||||
s += v[i];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST_RETURN
|
||||
extern std::vector<double> stdvector_fill_and_return_helper();
|
||||
|
||||
void tst_QVector::stdvector_fill_and_return()
|
||||
{
|
||||
QBENCHMARK {
|
||||
std::vector<double> v = stdvector_fill_and_return_helper();
|
||||
s += v[1];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////// mixed vector /////////////////////
|
||||
|
||||
|
||||
#ifdef TEST_RETURN
|
||||
extern QVector<double> mixedvector_fill_and_return_helper();
|
||||
|
||||
void tst_QVector::mixedvector_fill_and_return()
|
||||
{
|
||||
QBENCHMARK {
|
||||
std::vector<double> v = stdvector_fill_and_return_helper();
|
||||
s += v[1];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
QTEST_MAIN(tst_QVector)
|
||||
|
||||
#include "moc_main.cpp"
|
81
tests/benchmarks/core/tools/qvector/outofline.cpp
Normal file
81
tests/benchmarks/core/tools/qvector/outofline.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtTest module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QVector>
|
||||
#include <vector>
|
||||
#include "qrawvector.h"
|
||||
|
||||
const int N = 1000000;
|
||||
double s = 0;
|
||||
|
||||
QVector<double> qvector_fill_and_return_helper()
|
||||
{
|
||||
QVector<double> v(N);
|
||||
for (int i = 0; i != N; ++i)
|
||||
v[i] = i;
|
||||
return v;
|
||||
}
|
||||
|
||||
QVector<double> qrawvector_fill_and_return_helper()
|
||||
{
|
||||
QRawVector<double> v(N);
|
||||
for (int i = 0; i != N; ++i)
|
||||
v[i] = i;
|
||||
return v.mutateToVector();
|
||||
}
|
||||
|
||||
QVector<double> mixedvector_fill_and_return_helper()
|
||||
{
|
||||
std::vector<double> v(N);
|
||||
for (int i = 0; i != N; ++i)
|
||||
v[i] = i;
|
||||
return QVector<double>::fromStdVector(v);
|
||||
}
|
||||
|
||||
|
||||
std::vector<double> stdvector_fill_and_return_helper()
|
||||
{
|
||||
std::vector<double> v(N);
|
||||
for (int i = 0; i != N; ++i)
|
||||
v[i] = i;
|
||||
return v;
|
||||
}
|
||||
|
738
tests/benchmarks/core/tools/qvector/qrawvector.h
Normal file
738
tests/benchmarks/core/tools/qvector/qrawvector.h
Normal file
|
@ -0,0 +1,738 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QRAWVECTOR_H
|
||||
#define QRAWVECTOR_H
|
||||
|
||||
#include <QtCore/qiterator.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qatomic.h>
|
||||
#include <QtCore/qalgorithms.h>
|
||||
#include <QtCore/qlist.h>
|
||||
|
||||
#ifndef QT_NO_STL
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
template <typename T>
|
||||
class QRawVector
|
||||
{
|
||||
struct Data : QVectorData { T array[1]; };
|
||||
|
||||
T *m_begin;
|
||||
int m_size;
|
||||
int m_alloc;
|
||||
|
||||
public:
|
||||
//static Data dummy;
|
||||
//int headerOffset() { return (char*)&dummy.array - (char*)&dummy; }
|
||||
inline int headerOffset() const {
|
||||
// gcc complains about: return offsetof(Data, array); and also
|
||||
// does not like '0' in the expression below.
|
||||
return (char *)&(((Data *)(1))->array) - (char *)1;
|
||||
}
|
||||
inline Data *toBase(T *begin) const
|
||||
{ return (Data*)((char*)begin - headerOffset()); }
|
||||
inline T *fromBase(void *d) const
|
||||
{ return (T*)((char*)d + headerOffset()); }
|
||||
inline QRawVector()
|
||||
{ m_begin = fromBase(0); m_alloc = m_size = 0; realloc(m_size, m_alloc, true); }
|
||||
explicit QRawVector(int size);
|
||||
QRawVector(int size, const T &t);
|
||||
inline QRawVector(const QRawVector<T> &v)
|
||||
{ m_begin = v.m_begin; m_alloc = v.m_alloc; m_size = v.m_size; realloc(m_size, m_alloc, true); }
|
||||
inline ~QRawVector() { free(m_begin, m_size); }
|
||||
QRawVector<T> &operator=(const QRawVector<T> &v);
|
||||
bool operator==(const QRawVector<T> &v) const;
|
||||
inline bool operator!=(const QRawVector<T> &v) const { return !(*this == v); }
|
||||
|
||||
inline int size() const { return m_size; }
|
||||
|
||||
inline bool isEmpty() const { return m_size == 0; }
|
||||
|
||||
void resize(int size);
|
||||
|
||||
inline int capacity() const { return m_alloc; }
|
||||
void reserve(int size);
|
||||
inline void squeeze() { realloc(m_size, m_size, false); }
|
||||
|
||||
inline T *data() { return m_begin; }
|
||||
inline const T *data() const { return m_begin; }
|
||||
inline const T *constData() const { return m_begin; }
|
||||
void clear();
|
||||
|
||||
const T &at(int i) const;
|
||||
T &operator[](int i);
|
||||
const T &operator[](int i) const;
|
||||
void append(const T &t);
|
||||
void prepend(const T &t);
|
||||
void insert(int i, const T &t);
|
||||
void insert(int i, int n, const T &t);
|
||||
void replace(int i, const T &t);
|
||||
void remove(int i);
|
||||
void remove(int i, int n);
|
||||
|
||||
QRawVector<T> &fill(const T &t, int size = -1);
|
||||
|
||||
int indexOf(const T &t, int from = 0) const;
|
||||
int lastIndexOf(const T &t, int from = -1) const;
|
||||
bool contains(const T &t) const;
|
||||
int count(const T &t) const;
|
||||
|
||||
#ifdef QT_STRICT_ITERATORS
|
||||
class iterator {
|
||||
public:
|
||||
T *i;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T value_type;
|
||||
typedef T *pointer;
|
||||
typedef T &reference;
|
||||
|
||||
inline iterator() : i(0) {}
|
||||
inline iterator(T *n) : i(n) {}
|
||||
inline iterator(const iterator &o): i(o.i){}
|
||||
inline T &operator*() const { return *i; }
|
||||
inline T *operator->() const { return i; }
|
||||
inline T &operator[](int j) const { return *(i + j); }
|
||||
inline bool operator==(const iterator &o) const { return i == o.i; }
|
||||
inline bool operator!=(const iterator &o) const { return i != o.i; }
|
||||
inline bool operator<(const iterator& other) const { return i < other.i; }
|
||||
inline bool operator<=(const iterator& other) const { return i <= other.i; }
|
||||
inline bool operator>(const iterator& other) const { return i > other.i; }
|
||||
inline bool operator>=(const iterator& other) const { return i >= other.i; }
|
||||
inline iterator &operator++() { ++i; return *this; }
|
||||
inline iterator operator++(int) { T *n = i; ++i; return n; }
|
||||
inline iterator &operator--() { i--; return *this; }
|
||||
inline iterator operator--(int) { T *n = i; i--; return n; }
|
||||
inline iterator &operator+=(int j) { i+=j; return *this; }
|
||||
inline iterator &operator-=(int j) { i-=j; return *this; }
|
||||
inline iterator operator+(int j) const { return iterator(i+j); }
|
||||
inline iterator operator-(int j) const { return iterator(i-j); }
|
||||
inline int operator-(iterator j) const { return i - j.i; }
|
||||
};
|
||||
friend class iterator;
|
||||
|
||||
class const_iterator {
|
||||
public:
|
||||
T *i;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T value_type;
|
||||
typedef const T *pointer;
|
||||
typedef const T &reference;
|
||||
|
||||
inline const_iterator() : i(0) {}
|
||||
inline const_iterator(T *n) : i(n) {}
|
||||
inline const_iterator(const const_iterator &o): i(o.i) {}
|
||||
inline explicit const_iterator(const iterator &o): i(o.i) {}
|
||||
inline const T &operator*() const { return *i; }
|
||||
inline const T *operator->() const { return i; }
|
||||
inline const T &operator[](int j) const { return *(i + j); }
|
||||
inline bool operator==(const const_iterator &o) const { return i == o.i; }
|
||||
inline bool operator!=(const const_iterator &o) const { return i != o.i; }
|
||||
inline bool operator<(const const_iterator& other) const { return i < other.i; }
|
||||
inline bool operator<=(const const_iterator& other) const { return i <= other.i; }
|
||||
inline bool operator>(const const_iterator& other) const { return i > other.i; }
|
||||
inline bool operator>=(const const_iterator& other) const { return i >= other.i; }
|
||||
inline const_iterator &operator++() { ++i; return *this; }
|
||||
inline const_iterator operator++(int) { T *n = i; ++i; return n; }
|
||||
inline const_iterator &operator--() { i--; return *this; }
|
||||
inline const_iterator operator--(int) { T *n = i; i--; return n; }
|
||||
inline const_iterator &operator+=(int j) { i+=j; return *this; }
|
||||
inline const_iterator &operator-=(int j) { i+=j; return *this; }
|
||||
inline const_iterator operator+(int j) const { return const_iterator(i+j); }
|
||||
inline const_iterator operator-(int j) const { return const_iterator(i-j); }
|
||||
inline int operator-(const_iterator j) const { return i - j.i; }
|
||||
};
|
||||
friend class const_iterator;
|
||||
#else
|
||||
// STL-style
|
||||
typedef T *iterator;
|
||||
typedef const T *const_iterator;
|
||||
#endif
|
||||
inline iterator begin() { return m_begin; }
|
||||
inline const_iterator begin() const { return m_begin; }
|
||||
inline const_iterator constBegin() const { return m_begin; }
|
||||
inline iterator end() { return m_begin + m_size; }
|
||||
inline const_iterator end() const { return m_begin + m_size; }
|
||||
inline const_iterator constEnd() const { return m_begin + m_size; }
|
||||
iterator insert(iterator before, int n, const T &x);
|
||||
inline iterator insert(iterator before, const T &x) { return insert(before, 1, x); }
|
||||
iterator erase(iterator begin, iterator end);
|
||||
inline iterator erase(iterator pos) { return erase(pos, pos+1); }
|
||||
|
||||
// more Qt
|
||||
inline int count() const { return m_size; }
|
||||
inline T& first() { Q_ASSERT(!isEmpty()); return *begin(); }
|
||||
inline const T &first() const { Q_ASSERT(!isEmpty()); return *begin(); }
|
||||
inline T& last() { Q_ASSERT(!isEmpty()); return *(end()-1); }
|
||||
inline const T &last() const { Q_ASSERT(!isEmpty()); return *(end()-1); }
|
||||
inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; }
|
||||
inline bool endsWith(const T &t) const { return !isEmpty() && last() == t; }
|
||||
QRawVector<T> mid(int pos, int length = -1) const;
|
||||
|
||||
T value(int i) const;
|
||||
T value(int i, const T &defaultValue) const;
|
||||
|
||||
// STL compatibility
|
||||
typedef T value_type;
|
||||
typedef value_type *pointer;
|
||||
typedef const value_type *const_pointer;
|
||||
typedef value_type &reference;
|
||||
typedef const value_type &const_reference;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef iterator Iterator;
|
||||
typedef const_iterator ConstIterator;
|
||||
typedef int size_type;
|
||||
inline void push_back(const T &t) { append(t); }
|
||||
inline void push_front(const T &t) { prepend(t); }
|
||||
void pop_back() { Q_ASSERT(!isEmpty()); erase(end()-1); }
|
||||
void pop_front() { Q_ASSERT(!isEmpty()); erase(begin()); }
|
||||
inline bool empty() const { return m_size == 0; }
|
||||
inline T &front() { return first(); }
|
||||
inline const_reference front() const { return first(); }
|
||||
inline reference back() { return last(); }
|
||||
inline const_reference back() const { return last(); }
|
||||
|
||||
// comfort
|
||||
QRawVector<T> &operator+=(const QRawVector<T> &l);
|
||||
inline QRawVector<T> operator+(const QRawVector<T> &l) const
|
||||
{ QRawVector n = *this; n += l; return n; }
|
||||
inline QRawVector<T> &operator+=(const T &t)
|
||||
{ append(t); return *this; }
|
||||
inline QRawVector<T> &operator<< (const T &t)
|
||||
{ append(t); return *this; }
|
||||
inline QRawVector<T> &operator<<(const QRawVector<T> &l)
|
||||
{ *this += l; return *this; }
|
||||
|
||||
QList<T> toList() const;
|
||||
|
||||
//static QRawVector<T> fromList(const QList<T> &list);
|
||||
|
||||
#ifndef QT_NO_STL
|
||||
static inline QRawVector<T> fromStdVector(const std::vector<T> &vector)
|
||||
{ QRawVector<T> tmp; qCopy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; }
|
||||
inline std::vector<T> toStdVector() const
|
||||
{ std::vector<T> tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
T *allocate(int alloc);
|
||||
void realloc(int size, int alloc, bool ref);
|
||||
void free(T *begin, int size);
|
||||
int sizeOfTypedData() {
|
||||
// this is more or less the same as sizeof(Data), except that it doesn't
|
||||
// count the padding at the end
|
||||
return reinterpret_cast<const char *>(&(reinterpret_cast<const Data *>(this))->array[1]) - reinterpret_cast<const char *>(this);
|
||||
}
|
||||
static inline int alignOfTypedData()
|
||||
{
|
||||
#ifdef Q_ALIGNOF
|
||||
return qMax<int>(sizeof(void*), Q_ALIGNOF(Data));
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
QVector<T> mutateToVector()
|
||||
{
|
||||
Data *d = toBase(m_begin);
|
||||
d->ref = 1;
|
||||
d->alloc = m_alloc;
|
||||
d->size = m_size;
|
||||
d->sharable = 0;
|
||||
d->capacity = 0;
|
||||
|
||||
QVector<T> v;
|
||||
*reinterpret_cast<QVectorData **>(&v) = d;
|
||||
m_begin = fromBase(0);
|
||||
m_size = m_alloc = 0;
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
void QRawVector<T>::reserve(int asize)
|
||||
{ if (asize > m_alloc) realloc(m_size, asize, false); }
|
||||
template <typename T>
|
||||
void QRawVector<T>::resize(int asize)
|
||||
{ realloc(asize, (asize > m_alloc || (asize < m_size && asize < (m_alloc >> 1)))
|
||||
? QVectorData::grow(sizeOfTypedData(), asize, sizeof(T), QTypeInfo<T>::isStatic)
|
||||
: m_alloc, false); }
|
||||
template <typename T>
|
||||
inline void QRawVector<T>::clear()
|
||||
{ *this = QRawVector<T>(); }
|
||||
template <typename T>
|
||||
inline const T &QRawVector<T>::at(int i) const
|
||||
{ Q_ASSERT_X(i >= 0 && i < m_size, "QRawVector<T>::at", "index out of range");
|
||||
return m_begin[i]; }
|
||||
template <typename T>
|
||||
inline const T &QRawVector<T>::operator[](int i) const
|
||||
{ Q_ASSERT_X(i >= 0 && i < m_size, "QRawVector<T>::operator[]", "index out of range");
|
||||
return m_begin[i]; }
|
||||
template <typename T>
|
||||
inline T &QRawVector<T>::operator[](int i)
|
||||
{ Q_ASSERT_X(i >= 0 && i < m_size, "QRawVector<T>::operator[]", "index out of range");
|
||||
return data()[i]; }
|
||||
template <typename T>
|
||||
inline void QRawVector<T>::insert(int i, const T &t)
|
||||
{ Q_ASSERT_X(i >= 0 && i <= m_size, "QRawVector<T>::insert", "index out of range");
|
||||
insert(begin() + i, 1, t); }
|
||||
template <typename T>
|
||||
inline void QRawVector<T>::insert(int i, int n, const T &t)
|
||||
{ Q_ASSERT_X(i >= 0 && i <= m_size, "QRawVector<T>::insert", "index out of range");
|
||||
insert(begin() + i, n, t); }
|
||||
template <typename T>
|
||||
inline void QRawVector<T>::remove(int i, int n)
|
||||
{ Q_ASSERT_X(i >= 0 && n >= 0 && i + n <= m_size, "QRawVector<T>::remove", "index out of range");
|
||||
erase(begin() + i, begin() + i + n); }
|
||||
template <typename T>
|
||||
inline void QRawVector<T>::remove(int i)
|
||||
{ Q_ASSERT_X(i >= 0 && i < m_size, "QRawVector<T>::remove", "index out of range");
|
||||
erase(begin() + i, begin() + i + 1); }
|
||||
template <typename T>
|
||||
inline void QRawVector<T>::prepend(const T &t)
|
||||
{ insert(begin(), 1, t); }
|
||||
|
||||
template <typename T>
|
||||
inline void QRawVector<T>::replace(int i, const T &t)
|
||||
{
|
||||
Q_ASSERT_X(i >= 0 && i < m_size, "QRawVector<T>::replace", "index out of range");
|
||||
const T copy(t);
|
||||
data()[i] = copy;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QRawVector<T> &QRawVector<T>::operator=(const QRawVector<T> &v)
|
||||
{
|
||||
if (this != &v) {
|
||||
free(m_begin, m_size);
|
||||
m_alloc = v.m_alloc;
|
||||
m_size = v.m_size;
|
||||
m_begin = v.m_begin;
|
||||
realloc(m_size, m_alloc, true);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T *QRawVector<T>::allocate(int aalloc)
|
||||
{
|
||||
QVectorData *d = QVectorData::allocate(sizeOfTypedData() + (aalloc - 1) * sizeof(T), alignOfTypedData());
|
||||
Q_CHECK_PTR(d);
|
||||
return fromBase(d);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QRawVector<T>::QRawVector(int asize)
|
||||
{
|
||||
m_size = m_alloc = asize;
|
||||
m_begin = allocate(asize);
|
||||
if (QTypeInfo<T>::isComplex) {
|
||||
T *b = m_begin;
|
||||
T *i = m_begin + m_size;
|
||||
while (i != b)
|
||||
new (--i) T;
|
||||
} else {
|
||||
qMemSet(m_begin, 0, asize * sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QRawVector<T>::QRawVector(int asize, const T &t)
|
||||
{
|
||||
m_size = m_alloc = asize;
|
||||
m_begin = allocate(asize);
|
||||
T *i = m_begin + m_size;
|
||||
while (i != m_begin)
|
||||
new (--i) T(t);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void QRawVector<T>::free(T *begin, int size)
|
||||
{
|
||||
if (QTypeInfo<T>::isComplex) {
|
||||
T *i = begin + size;
|
||||
while (i-- != begin)
|
||||
i->~T();
|
||||
}
|
||||
Data *x = toBase(begin);
|
||||
x->free(x, alignOfTypedData());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void QRawVector<T>::realloc(int asize, int aalloc, bool ref)
|
||||
{
|
||||
if (QTypeInfo<T>::isComplex && asize < m_size && !ref) {
|
||||
// call the destructor on all objects that need to be
|
||||
// destroyed when shrinking
|
||||
T *pOld = m_begin + m_size;
|
||||
while (asize < m_size) {
|
||||
(--pOld)->~T();
|
||||
--m_size;
|
||||
}
|
||||
}
|
||||
|
||||
int xalloc = m_alloc;
|
||||
int xsize = m_size;
|
||||
bool changed = false;
|
||||
T *xbegin = m_begin;
|
||||
if (aalloc != xalloc || ref) {
|
||||
// (re)allocate memory
|
||||
if (QTypeInfo<T>::isStatic) {
|
||||
xbegin = allocate(aalloc);
|
||||
xsize = 0;
|
||||
changed = true;
|
||||
} else if (ref) {
|
||||
xbegin = allocate(aalloc);
|
||||
if (QTypeInfo<T>::isComplex) {
|
||||
xsize = 0;
|
||||
} else {
|
||||
::memcpy(xbegin, m_begin, qMin(aalloc, xalloc) * sizeof(T));
|
||||
xsize = m_size;
|
||||
}
|
||||
changed = true;
|
||||
} else {
|
||||
QT_TRY {
|
||||
QVectorData *mem = QVectorData::reallocate(
|
||||
toBase(m_begin), sizeOfTypedData() + (aalloc - 1) * sizeof(T),
|
||||
sizeOfTypedData()
|
||||
+ (xalloc - 1) * sizeof(T), alignOfTypedData());
|
||||
Q_CHECK_PTR(mem);
|
||||
xbegin = fromBase(mem);
|
||||
xsize = m_size;
|
||||
} QT_CATCH (const std::bad_alloc &) {
|
||||
if (aalloc > xalloc) // ignore the error in case we are just shrinking.
|
||||
QT_RETHROW;
|
||||
}
|
||||
}
|
||||
xalloc = aalloc;
|
||||
}
|
||||
|
||||
if (QTypeInfo<T>::isComplex) {
|
||||
QT_TRY {
|
||||
T *pOld = m_begin + xsize;
|
||||
T *pNew = xbegin + xsize;
|
||||
// copy objects from the old array into the new array
|
||||
while (xsize < qMin(asize, m_size)) {
|
||||
new (pNew++) T(*pOld++);
|
||||
++xsize;
|
||||
}
|
||||
// construct all new objects when growing
|
||||
while (xsize < asize) {
|
||||
new (pNew++) T;
|
||||
++xsize;
|
||||
}
|
||||
} QT_CATCH (...) {
|
||||
free(xbegin, xsize);
|
||||
QT_RETHROW;
|
||||
}
|
||||
|
||||
} else if (asize > xsize) {
|
||||
// initialize newly allocated memory to 0
|
||||
qMemSet(xbegin + xsize, 0, (asize - xsize) * sizeof(T));
|
||||
}
|
||||
xsize = asize;
|
||||
|
||||
if (changed) {
|
||||
if (!ref)
|
||||
free(m_begin, m_size);
|
||||
}
|
||||
m_alloc = xalloc;
|
||||
m_size = xsize;
|
||||
m_begin = xbegin;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Q_OUTOFLINE_TEMPLATE T QRawVector<T>::value(int i) const
|
||||
{
|
||||
return (i < 0 || i >= m_size) ? T() : m_begin[i];
|
||||
}
|
||||
template<typename T>
|
||||
Q_OUTOFLINE_TEMPLATE T QRawVector<T>::value(int i, const T &defaultValue) const
|
||||
{
|
||||
return (i < 0 || i >= m_size) ? defaultValue : m_begin[i];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void QRawVector<T>::append(const T &t)
|
||||
{
|
||||
if (m_size + 1 > m_alloc) {
|
||||
const T copy(t);
|
||||
realloc(m_size, QVectorData::grow(sizeOfTypedData(), m_size + 1, sizeof(T),
|
||||
QTypeInfo<T>::isStatic), false);
|
||||
if (QTypeInfo<T>::isComplex)
|
||||
new (m_begin + m_size) T(copy);
|
||||
else
|
||||
m_begin[m_size] = copy;
|
||||
} else {
|
||||
if (QTypeInfo<T>::isComplex)
|
||||
new (m_begin + m_size) T(t);
|
||||
else
|
||||
m_begin[m_size] = t;
|
||||
}
|
||||
++m_size;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_TYPENAME QRawVector<T>::iterator QRawVector<T>::insert(iterator before, size_type n, const T &t)
|
||||
{
|
||||
int offset = int(before - m_begin);
|
||||
if (n != 0) {
|
||||
const T copy(t);
|
||||
if (m_size + n > m_alloc)
|
||||
realloc(m_size, QVectorData::grow(sizeOfTypedData(), m_size + n, sizeof(T),
|
||||
QTypeInfo<T>::isStatic), false);
|
||||
if (QTypeInfo<T>::isStatic) {
|
||||
T *b = m_begin + m_size;
|
||||
T *i = m_begin + m_size + n;
|
||||
while (i != b)
|
||||
new (--i) T;
|
||||
i = m_begin + m_size;
|
||||
T *j = i + n;
|
||||
b = m_begin + offset;
|
||||
while (i != b)
|
||||
*--j = *--i;
|
||||
i = b+n;
|
||||
while (i != b)
|
||||
*--i = copy;
|
||||
} else {
|
||||
T *b = m_begin + offset;
|
||||
T *i = b + n;
|
||||
memmove(i, b, (m_size - offset) * sizeof(T));
|
||||
while (i != b)
|
||||
new (--i) T(copy);
|
||||
}
|
||||
m_size += n;
|
||||
}
|
||||
return m_begin + offset;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_TYPENAME QRawVector<T>::iterator QRawVector<T>::erase(iterator abegin, iterator aend)
|
||||
{
|
||||
int f = int(abegin - m_begin);
|
||||
int l = int(aend - m_begin);
|
||||
int n = l - f;
|
||||
if (QTypeInfo<T>::isComplex) {
|
||||
qCopy(m_begin + l, m_begin + m_size, m_begin + f);
|
||||
T *i = m_begin + m_size;
|
||||
T *b = m_begin + m_size - n;
|
||||
while (i != b) {
|
||||
--i;
|
||||
i->~T();
|
||||
}
|
||||
} else {
|
||||
memmove(m_begin + f, m_begin + l, (m_size - l) * sizeof(T));
|
||||
}
|
||||
m_size -= n;
|
||||
return m_begin + f;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool QRawVector<T>::operator==(const QRawVector<T> &v) const
|
||||
{
|
||||
if (m_size != v.m_size)
|
||||
return false;
|
||||
T* b = m_begin;
|
||||
T* i = b + m_size;
|
||||
T* j = v.m_begin + m_size;
|
||||
while (i != b)
|
||||
if (!(*--i == *--j))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QRawVector<T> &QRawVector<T>::fill(const T &from, int asize)
|
||||
{
|
||||
const T copy(from);
|
||||
resize(asize < 0 ? m_size : asize);
|
||||
if (m_size) {
|
||||
T *i = m_begin + m_size;
|
||||
T *b = m_begin;
|
||||
while (i != b)
|
||||
*--i = copy;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QRawVector<T> &QRawVector<T>::operator+=(const QRawVector &l)
|
||||
{
|
||||
int newSize = m_size + l.m_size;
|
||||
realloc(m_size, newSize, false);
|
||||
|
||||
T *w = m_begin + newSize;
|
||||
T *i = l.m_begin + l.m_size;
|
||||
T *b = l.m_begin;
|
||||
while (i != b) {
|
||||
if (QTypeInfo<T>::isComplex)
|
||||
new (--w) T(*--i);
|
||||
else
|
||||
*--w = *--i;
|
||||
}
|
||||
m_size = newSize;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int QRawVector<T>::indexOf(const T &t, int from) const
|
||||
{
|
||||
if (from < 0)
|
||||
from = qMax(from + m_size, 0);
|
||||
if (from < m_size) {
|
||||
T* n = m_begin + from - 1;
|
||||
T* e = m_begin + m_size;
|
||||
while (++n != e)
|
||||
if (*n == t)
|
||||
return n - m_begin;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int QRawVector<T>::lastIndexOf(const T &t, int from) const
|
||||
{
|
||||
if (from < 0)
|
||||
from += m_size;
|
||||
else if (from >= m_size)
|
||||
from = m_size-1;
|
||||
if (from >= 0) {
|
||||
T* b = m_begin;
|
||||
T* n = m_begin + from + 1;
|
||||
while (n != b) {
|
||||
if (*--n == t)
|
||||
return n - b;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool QRawVector<T>::contains(const T &t) const
|
||||
{
|
||||
T* b = m_begin;
|
||||
T* i = m_begin + m_size;
|
||||
while (i != b)
|
||||
if (*--i == t)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int QRawVector<T>::count(const T &t) const
|
||||
{
|
||||
int c = 0;
|
||||
T* b = m_begin;
|
||||
T* i = m_begin + m_size;
|
||||
while (i != b)
|
||||
if (*--i == t)
|
||||
++c;
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_OUTOFLINE_TEMPLATE QRawVector<T> QRawVector<T>::mid(int pos, int length) const
|
||||
{
|
||||
if (length < 0)
|
||||
length = size() - pos;
|
||||
if (pos == 0 && length == size())
|
||||
return *this;
|
||||
QRawVector<T> copy;
|
||||
if (pos + length > size())
|
||||
length = size() - pos;
|
||||
for (int i = pos; i < pos + length; ++i)
|
||||
copy += at(i);
|
||||
return copy;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_OUTOFLINE_TEMPLATE QList<T> QRawVector<T>::toList() const
|
||||
{
|
||||
QList<T> result;
|
||||
for (int i = 0; i < size(); ++i)
|
||||
result.append(at(i));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*template <typename T>
|
||||
Q_OUTOFLINE_TEMPLATE QRawVector<T> QList<T>::toVector() const
|
||||
{
|
||||
QRawVector<T> result(size());
|
||||
for (int i = 0; i < size(); ++i)
|
||||
result[i] = at(i);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QRawVector<T> QRawVector<T>::fromList(const QList<T> &list)
|
||||
{
|
||||
return list.toVector();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QList<T> QList<T>::fromVector(const QRawVector<T> &vector)
|
||||
{
|
||||
return vector.toList();
|
||||
}
|
||||
*/
|
||||
|
||||
Q_DECLARE_SEQUENTIAL_ITERATOR(RawVector)
|
||||
Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(RawVector)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // QRAWVECTOR_H
|
2
tests/benchmarks/dbus/qdbusperformance/.gitignore
vendored
Normal file
2
tests/benchmarks/dbus/qdbusperformance/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
tst_qdbusperformance
|
||||
server/server
|
16
tests/benchmarks/dbus/qdbusperformance/CMakeLists.txt
Normal file
16
tests/benchmarks/dbus/qdbusperformance/CMakeLists.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
if(WITH_DBUS AND DBUS_FOUND)
|
||||
katie_test(tst_qdbusperformance
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tst_qdbusperformance.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/serverobject.h
|
||||
)
|
||||
|
||||
target_link_libraries(tst_qdbusperformance KtDBus)
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_executable(server
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/server/server.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/serverobject.h
|
||||
)
|
||||
|
||||
target_link_libraries(server KtDBus)
|
||||
endif()
|
65
tests/benchmarks/dbus/qdbusperformance/server/server.cpp
Normal file
65
tests/benchmarks/dbus/qdbusperformance/server/server.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#include <QtCore/QtCore>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
#include "../serverobject.h"
|
||||
|
||||
static const char serviceName[] = "com.trolltech.autotests.performance";
|
||||
static const char objectPath[] = "/";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
if (!con.isConnected())
|
||||
exit(1);
|
||||
|
||||
if (!con.registerService(serviceName))
|
||||
exit(2);
|
||||
|
||||
ServerObject obj(objectPath, con);
|
||||
printf("ready.\n");
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
#include "moc_serverobject.h"
|
115
tests/benchmarks/dbus/qdbusperformance/serverobject.h
Normal file
115
tests/benchmarks/dbus/qdbusperformance/serverobject.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef SERVEROBJECT_H
|
||||
#define SERVEROBJECT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
class ServerObject: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "com.trolltech.autotests.Performance")
|
||||
public:
|
||||
ServerObject(const QString &objectPath, QDBusConnection conn, QObject *parent = 0)
|
||||
: QObject(parent)
|
||||
{
|
||||
conn.registerObject(objectPath, this, QDBusConnection::ExportAllSlots);
|
||||
}
|
||||
|
||||
public slots:
|
||||
Q_NOREPLY void noReply(const QByteArray &)
|
||||
{
|
||||
// black hole
|
||||
}
|
||||
Q_NOREPLY void noReply(const QString &)
|
||||
{
|
||||
// black hole
|
||||
}
|
||||
Q_NOREPLY void noReply(const QDBusVariant &)
|
||||
{
|
||||
// black hole
|
||||
}
|
||||
|
||||
int size(const QByteArray &data)
|
||||
{
|
||||
return data.size();
|
||||
}
|
||||
int size(const QString &data)
|
||||
{
|
||||
return data.size();
|
||||
}
|
||||
int size(const QDBusVariant &data)
|
||||
{
|
||||
QVariant v = data.variant();
|
||||
switch (v.type())
|
||||
{
|
||||
case QVariant::ByteArray:
|
||||
return v.toByteArray().size();
|
||||
case QVariant::StringList:
|
||||
return v.toStringList().size();
|
||||
case QVariant::String:
|
||||
default:
|
||||
return v.toString().size();
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray echo(const QByteArray &data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
QString echo(const QString &data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
QDBusVariant echo(const QDBusVariant &data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
void nothing()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
232
tests/benchmarks/dbus/qdbusperformance/tst_qdbusperformance.cpp
Normal file
232
tests/benchmarks/dbus/qdbusperformance/tst_qdbusperformance.cpp
Normal file
|
@ -0,0 +1,232 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
#include <QtCore/QtCore>
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
#include "./serverobject.h"
|
||||
|
||||
static const char serviceName[] = "com.trolltech.autotests.performance";
|
||||
static const int runTime = 500;
|
||||
|
||||
class tst_QDBusPerformance: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QProcess proc;
|
||||
QDBusInterface *target;
|
||||
|
||||
QDBusInterface *remote;
|
||||
QDBusInterface *local;
|
||||
|
||||
bool executeTest(const char *funcname, int size, const QVariant &data);
|
||||
|
||||
public slots:
|
||||
void initTestCase_data();
|
||||
void initTestCase();
|
||||
void init();
|
||||
|
||||
private slots:
|
||||
void callSpeed();
|
||||
|
||||
void oneWay_data();
|
||||
void oneWay();
|
||||
void oneWayVariant_data();
|
||||
void oneWayVariant();
|
||||
|
||||
void roundTrip_data();
|
||||
void roundTrip();
|
||||
void roundTripVariant_data();
|
||||
void roundTripVariant();
|
||||
};
|
||||
Q_DECLARE_METATYPE(QVariant)
|
||||
|
||||
void tst_QDBusPerformance::initTestCase()
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
QVERIFY(con.isConnected());
|
||||
|
||||
QDBusServiceWatcher watcher(serviceName, con,
|
||||
QDBusServiceWatcher::WatchForRegistration);
|
||||
connect(&watcher, SIGNAL(serviceRegistered(QString)),
|
||||
&QTestEventLoop::instance(), SLOT(exitLoop()));
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
proc.start("server");
|
||||
#else
|
||||
proc.start("./server/server");
|
||||
#endif
|
||||
QVERIFY(proc.waitForStarted());
|
||||
|
||||
QTestEventLoop::instance().enterLoop(5);
|
||||
QVERIFY(con.interface()->isServiceRegistered(serviceName));
|
||||
|
||||
remote = new QDBusInterface(serviceName, "/", "com.trolltech.autotests.Performance", con, this);
|
||||
QVERIFY(remote->isValid());
|
||||
|
||||
new ServerObject("/", con, this);
|
||||
local = new QDBusInterface(con.baseService(), "/", "com.trolltech.autotests.Performance", con, this);
|
||||
QVERIFY(local->isValid());
|
||||
}
|
||||
|
||||
void tst_QDBusPerformance::initTestCase_data()
|
||||
{
|
||||
QTest::addColumn<bool>("loopback");
|
||||
|
||||
QTest::newRow("normal") << false;
|
||||
QTest::newRow("loopback") << true;
|
||||
}
|
||||
|
||||
void tst_QDBusPerformance::init()
|
||||
{
|
||||
QFETCH_GLOBAL(bool, loopback);
|
||||
if (loopback)
|
||||
target = local;
|
||||
else
|
||||
target = remote;
|
||||
}
|
||||
|
||||
void tst_QDBusPerformance::callSpeed()
|
||||
{
|
||||
QElapsedTimer timer;
|
||||
|
||||
int callCount = 0;
|
||||
timer.start();
|
||||
while (timer.elapsed() < runTime) {
|
||||
QDBusReply<void> reply = target->call("nothing");
|
||||
QVERIFY(reply.isValid());
|
||||
|
||||
++callCount;
|
||||
}
|
||||
qDebug() << callCount << "calls in" << timer.elapsed() << "ms:"
|
||||
<< (callCount * 1000.0 / timer.elapsed()) << "calls/sec";
|
||||
}
|
||||
|
||||
bool tst_QDBusPerformance::executeTest(const char *funcname, int size, const QVariant &data)
|
||||
{
|
||||
QElapsedTimer timer;
|
||||
|
||||
int callCount = 0;
|
||||
qint64 transferred = 0;
|
||||
timer.start();
|
||||
while (timer.elapsed() < runTime) {
|
||||
QDBusMessage reply = target->call(funcname, data);
|
||||
if (reply.type() != QDBusMessage::ReplyMessage)
|
||||
return false;
|
||||
|
||||
transferred += size;
|
||||
++callCount;
|
||||
}
|
||||
qDebug() << transferred << "bytes in" << timer.elapsed() << "ms"
|
||||
<< "(in" << callCount << "calls):"
|
||||
<< (transferred * 1000.0 / timer.elapsed() / 1024 / 1024) << "MB/s";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void tst_QDBusPerformance::oneWay_data()
|
||||
{
|
||||
QTest::addColumn<QVariant>("data");
|
||||
QTest::addColumn<int>("size");
|
||||
|
||||
QByteArray ba(256, 'a');
|
||||
while (ba.size() < 8193) {
|
||||
QTest::newRow(QString("%1-byteArray").arg(ba.size()).toAscii()) << qVariantFromValue(ba) << ba.size();
|
||||
ba += ba;
|
||||
}
|
||||
|
||||
QString s(256, QLatin1Char('a'));
|
||||
while (s.size() < 8193) {
|
||||
QTest::newRow(QString("%1-string").arg(s.size()).toAscii()) << qVariantFromValue(s) << s.size();
|
||||
s += s;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QDBusPerformance::oneWay()
|
||||
{
|
||||
QFETCH(QVariant, data);
|
||||
QFETCH(int, size);
|
||||
|
||||
QVERIFY(executeTest("size", size, data));
|
||||
}
|
||||
|
||||
void tst_QDBusPerformance::oneWayVariant_data()
|
||||
{
|
||||
oneWay_data();
|
||||
}
|
||||
|
||||
void tst_QDBusPerformance::oneWayVariant()
|
||||
{
|
||||
QFETCH(QVariant, data);
|
||||
QFETCH(int, size);
|
||||
|
||||
QVERIFY(executeTest("size", size, qVariantFromValue(QDBusVariant(data))));
|
||||
}
|
||||
|
||||
void tst_QDBusPerformance::roundTrip_data()
|
||||
{
|
||||
oneWay_data();
|
||||
}
|
||||
|
||||
void tst_QDBusPerformance::roundTrip()
|
||||
{
|
||||
QFETCH(QVariant, data);
|
||||
QFETCH(int, size);
|
||||
|
||||
QVERIFY(executeTest("echo", size, data));
|
||||
}
|
||||
|
||||
void tst_QDBusPerformance::roundTripVariant_data()
|
||||
{
|
||||
oneWay_data();
|
||||
}
|
||||
|
||||
void tst_QDBusPerformance::roundTripVariant()
|
||||
{
|
||||
QFETCH(QVariant, data);
|
||||
QFETCH(int, size);
|
||||
|
||||
QVERIFY(executeTest("echo", size, qVariantFromValue(QDBusVariant(data))));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDBusPerformance)
|
||||
|
||||
#include "moc_tst_qdbusperformance.cpp"
|
||||
#include "moc_serverobject.h"
|
8
tests/benchmarks/dbus/qdbustype/CMakeLists.txt
Normal file
8
tests/benchmarks/dbus/qdbustype/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
if(WITH_DBUS AND DBUS_FOUND)
|
||||
katie_test(tst_bench_qdbustype
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(tst_bench_qdbustype KtDBus)
|
||||
include_directories(${DBUS_INCLUDES})
|
||||
endif()
|
115
tests/benchmarks/dbus/qdbustype/main.cpp
Normal file
115
tests/benchmarks/dbus/qdbustype/main.cpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the FOO module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** 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 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
#include <QtDBus/qdbusutil_p.h>
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
class tst_QDBusType: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void benchmarkSignature_data();
|
||||
void benchmarkSignature();
|
||||
};
|
||||
|
||||
static inline void benchmarkAddRow(const char *name, const char *data)
|
||||
{
|
||||
QTest::newRow(QByteArray("native-") + name) << data << true;
|
||||
QTest::newRow(name) << data << false;
|
||||
}
|
||||
|
||||
void tst_QDBusType::benchmarkSignature_data()
|
||||
{
|
||||
QTest::addColumn<QString>("data");
|
||||
QTest::addColumn<bool>("useNative");
|
||||
|
||||
for (int loopCount = 0; loopCount < 2; ++loopCount) {
|
||||
bool useNative = loopCount;
|
||||
QByteArray prefix = useNative ? "native-" : "";
|
||||
|
||||
benchmarkAddRow("single-invalid", "~");
|
||||
benchmarkAddRow("single-invalid-array", "a~");
|
||||
benchmarkAddRow("single-invalid-struct", "(.)");
|
||||
|
||||
benchmarkAddRow("single-char", "b");
|
||||
benchmarkAddRow("single-array", "as");
|
||||
benchmarkAddRow("single-simplestruct", "(y)");
|
||||
benchmarkAddRow("single-simpledict", "a{sv}");
|
||||
benchmarkAddRow("single-complexdict", "a{s(aya{io})}");
|
||||
|
||||
benchmarkAddRow("multiple-char", "ssg");
|
||||
benchmarkAddRow("multiple-arrays", "asasay");
|
||||
|
||||
benchmarkAddRow("struct-missingclose", "(ayyyy");
|
||||
benchmarkAddRow("longstruct", "(yyyyyyayasy)");
|
||||
benchmarkAddRow("invalid-longstruct", "(yyyyyyayas.y)");
|
||||
benchmarkAddRow("complexstruct", "(y(aasay)oga{sv})");
|
||||
benchmarkAddRow("multiple-simple-structs", "(y)(y)(y)");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QDBusType::benchmarkSignature()
|
||||
{
|
||||
QFETCH(QString, data);
|
||||
QFETCH(bool, useNative);
|
||||
|
||||
bool result;
|
||||
if (useNative) {
|
||||
dbus_signature_validate(data.toLatin1(), 0);
|
||||
QBENCHMARK {
|
||||
result = dbus_signature_validate(data.toLatin1(), 0);
|
||||
}
|
||||
} else {
|
||||
QDBusUtil::isValidSignature(data);
|
||||
QBENCHMARK {
|
||||
result = QDBusUtil::isValidSignature(data);
|
||||
}
|
||||
}
|
||||
Q_UNUSED(result);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDBusType)
|
||||
|
||||
#include "moc_main.cpp"
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue