734 lines
21 KiB
C++
734 lines
21 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
** Contact: https://www.qt.io/licensing/
|
|
**
|
|
** This file is part of the test suite of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
|
** 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 https://www.qt.io/terms-conditions. For further
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
|
**
|
|
** GNU General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
** General Public License version 3 as published by the Free Software
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
** included in the packaging of this file. Please review the following
|
|
** information to ensure the GNU General Public License requirements will
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
|
|
#include <QDebug>
|
|
#include <QTemporaryFile>
|
|
#include <QString>
|
|
#include <QDirIterator>
|
|
|
|
#include <private/qfsfileengine_p.h>
|
|
|
|
#include <qtest.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#ifdef Q_OS_WIN
|
|
# include <windows.h>
|
|
#endif
|
|
|
|
#if defined(Q_OS_QNX) && defined(open)
|
|
#undef open
|
|
#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,
|
|
#ifdef QT_BUILD_INTERNAL
|
|
QFSFileEngineBenchmark,
|
|
#endif
|
|
Win32Benchmark,
|
|
PosixBenchmark,
|
|
QFileFromPosixBenchmark
|
|
};
|
|
private slots:
|
|
void initTestCase();
|
|
void cleanupTestCase();
|
|
|
|
void open_data();
|
|
void open();
|
|
void seek_data();
|
|
void seek();
|
|
|
|
void readSmallFiles_QFile();
|
|
void readSmallFiles_QFSFileEngine();
|
|
void readSmallFiles_posix();
|
|
void readSmallFiles_Win32();
|
|
|
|
void readSmallFiles_QFile_data();
|
|
void readSmallFiles_QFSFileEngine_data();
|
|
void readSmallFiles_posix_data();
|
|
void readSmallFiles_Win32_data();
|
|
|
|
void readBigFile_QFile_data();
|
|
void readBigFile_QFSFileEngine_data();
|
|
void readBigFile_posix_data();
|
|
void readBigFile_Win32_data();
|
|
|
|
void readBigFile_QFile();
|
|
void readBigFile_QFSFileEngine();
|
|
void readBigFile_posix();
|
|
void readBigFile_Win32();
|
|
|
|
private:
|
|
void readBigFile_data(BenchmarkType type, QIODevice::OpenModeFlag t, QIODevice::OpenModeFlag b);
|
|
void readBigFile();
|
|
void readSmallFiles_data(BenchmarkType type, QIODevice::OpenModeFlag t, QIODevice::OpenModeFlag b);
|
|
void readSmallFiles();
|
|
void createFile();
|
|
void fillFile(int factor=FACTOR);
|
|
void removeFile();
|
|
void createSmallFiles();
|
|
void removeSmallFiles();
|
|
QString filename;
|
|
QString tmpDirName;
|
|
};
|
|
|
|
Q_DECLARE_METATYPE(tst_qfile::BenchmarkType)
|
|
Q_DECLARE_METATYPE(QIODevice::OpenMode)
|
|
Q_DECLARE_METATYPE(QIODevice::OpenModeFlag)
|
|
|
|
void tst_qfile::createFile()
|
|
{
|
|
removeFile(); // Cleanup in case previous test case aborted before cleaning up
|
|
|
|
QTemporaryFile tmpFile;
|
|
tmpFile.setAutoRemove(false);
|
|
if (!tmpFile.open())
|
|
::exit(1);
|
|
filename = tmpFile.fileName();
|
|
tmpFile.close();
|
|
}
|
|
|
|
void tst_qfile::removeFile()
|
|
{
|
|
if (!filename.isEmpty())
|
|
QFile::remove(filename);
|
|
}
|
|
|
|
void tst_qfile::fillFile(int factor)
|
|
{
|
|
QFile tmpFile(filename);
|
|
tmpFile.open(QIODevice::WriteOnly);
|
|
//for (int row=0; row<factor; ++row) {
|
|
// tmpFile.write(QByteArray().fill('0'+row%('0'-'z'), 80));
|
|
// tmpFile.write("\n");
|
|
//}
|
|
tmpFile.seek(factor*80);
|
|
tmpFile.putChar('\n');
|
|
tmpFile.close();
|
|
// let IO settle
|
|
QTest::qSleep(2000);
|
|
}
|
|
|
|
void tst_qfile::initTestCase()
|
|
{
|
|
}
|
|
|
|
void tst_qfile::cleanupTestCase()
|
|
{
|
|
}
|
|
|
|
void tst_qfile::readBigFile_QFile() { readBigFile(); }
|
|
void tst_qfile::readBigFile_QFSFileEngine()
|
|
{
|
|
#ifdef QT_BUILD_INTERNAL
|
|
readBigFile();
|
|
#else
|
|
QSKIP("This test requires -developer-build.");
|
|
#endif
|
|
}
|
|
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()
|
|
{
|
|
#ifdef QT_BUILD_INTERNAL
|
|
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);
|
|
#else
|
|
QTest::addColumn<int>("dummy");
|
|
QTest::newRow("Test will be skipped") << -1;
|
|
#endif
|
|
}
|
|
|
|
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.");
|
|
#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;
|
|
#ifdef QT_BUILD_INTERNAL
|
|
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;
|
|
#endif
|
|
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();
|
|
|
|
#ifndef Q_OS_WINRT
|
|
hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
|
|
#else
|
|
hndl = CreateFile2(cfilename, GENERIC_READ, 0, OPEN_EXISTING, 0);
|
|
#endif
|
|
Q_ASSERT(hndl);
|
|
wchar_t* nativeBuffer = new wchar_t[BUFSIZE];
|
|
DWORD numberOfBytesRead;
|
|
|
|
QBENCHMARK {
|
|
do {
|
|
ReadFile(hndl, nativeBuffer, blockSize, &numberOfBytesRead, NULL);
|
|
} while(numberOfBytesRead != 0);
|
|
#ifndef Q_OS_WINRT
|
|
SetFilePointer(hndl, 0, NULL, FILE_BEGIN);
|
|
#else
|
|
LARGE_INTEGER offset = { 0 };
|
|
SetFilePointerEx(hndl, offset, NULL, FILE_BEGIN);
|
|
#endif
|
|
}
|
|
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;
|
|
#ifdef QT_BUILD_INTERNAL
|
|
QTest::newRow("QFSFileEngine") << QFSFileEngineBenchmark;
|
|
#endif
|
|
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;
|
|
#ifdef QT_BUILD_INTERNAL
|
|
case(QFSFileEngineBenchmark): {
|
|
QFSFileEngine fse(filename);
|
|
fse.open(QIODevice::ReadOnly);
|
|
QBENCHMARK {
|
|
i=(i+1)%sp_size;
|
|
fse.seek(seekpos[i]);
|
|
}
|
|
fse.close();
|
|
}
|
|
break;
|
|
#endif
|
|
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();
|
|
|
|
#ifndef Q_OS_WINRT
|
|
hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
|
|
#else
|
|
hndl = CreateFile2(cfilename, GENERIC_READ, 0, OPEN_EXISTING, 0);
|
|
#endif
|
|
Q_ASSERT(hndl);
|
|
QBENCHMARK {
|
|
i=(i+1)%sp_size;
|
|
#ifndef Q_OS_WINRT
|
|
SetFilePointer(hndl, seekpos[i], NULL, 0);
|
|
#else
|
|
LARGE_INTEGER offset = { seekpos[i] };
|
|
SetFilePointerEx(hndl, offset, NULL, FILE_BEGIN);
|
|
#endif
|
|
}
|
|
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;
|
|
#ifdef QT_BUILD_INTERNAL
|
|
QTest::newRow("QFSFileEngine") << QFSFileEngineBenchmark;
|
|
#endif
|
|
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;
|
|
#ifdef QT_BUILD_INTERNAL
|
|
case(QFSFileEngineBenchmark): {
|
|
QBENCHMARK {
|
|
QFSFileEngine fse(filename);
|
|
fse.open(QIODevice::ReadOnly);
|
|
fse.close();
|
|
}
|
|
}
|
|
break;
|
|
#endif
|
|
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 {
|
|
#ifndef Q_OS_WINRT
|
|
hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
|
|
#else
|
|
hndl = CreateFile2(cfilename, GENERIC_READ, 0, OPEN_EXISTING, 0);
|
|
#endif
|
|
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()
|
|
{
|
|
#ifdef QT_BUILD_INTERNAL
|
|
readSmallFiles();
|
|
#else
|
|
QSKIP("This test requires -developer-build.");
|
|
#endif
|
|
}
|
|
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()
|
|
{
|
|
#ifdef QT_BUILD_INTERNAL
|
|
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);
|
|
#else
|
|
QTest::addColumn<int>("dummy");
|
|
QTest::newRow("Test will be skipped") << -1;
|
|
#endif
|
|
}
|
|
|
|
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();
|
|
|
|
for (int i = 0; i < 1000; ++i) {
|
|
QFile f(tmpDirName + QLatin1Char('/') + 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.");
|
|
#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 + QLatin1Char('/') + 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;
|
|
#ifdef QT_BUILD_INTERNAL
|
|
case(QFSFileEngineBenchmark): {
|
|
QList<QFSFileEngine*> fileList;
|
|
Q_FOREACH(QString file, files) {
|
|
QFSFileEngine *fse = new QFSFileEngine(tmpDirName + QLatin1Char('/') + 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;
|
|
#endif
|
|
case(PosixBenchmark): {
|
|
QList<FILE*> fileList;
|
|
Q_FOREACH(QString file, files) {
|
|
fileList.append(::fopen(QFile::encodeName(tmpDirName + QLatin1Char('/') + 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();
|
|
|
|
#ifndef Q_OS_WINRT
|
|
hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
|
|
#else
|
|
hndl = CreateFile2(cfilename, GENERIC_READ, 0, OPEN_EXISTING, 0);
|
|
#endif
|
|
Q_ASSERT(hndl);
|
|
wchar_t* nativeBuffer = new wchar_t[BUFSIZE];
|
|
DWORD numberOfBytesRead;
|
|
QBENCHMARK {
|
|
do {
|
|
ReadFile(hndl, nativeBuffer, blockSize, &numberOfBytesRead, NULL);
|
|
} while(numberOfBytesRead != 0);
|
|
}
|
|
delete nativeBuffer;
|
|
CloseHandle(hndl);
|
|
#else
|
|
QFAIL("Not running on a non-Windows platform!");
|
|
#endif
|
|
}
|
|
break;
|
|
}
|
|
|
|
removeSmallFiles();
|
|
delete[] buffer;
|
|
}
|
|
|
|
QTEST_MAIN(tst_qfile)
|
|
|
|
#include "main.moc"
|