From 053e8c41d7f87a07cb1a74cd95bd030ac138dc4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Tue, 28 Oct 2014 12:21:13 +0100 Subject: Use file mapping in moc. The change reduces heap allocations by using file mapping instead of reading a whole file into memory just to create a slightly modified copy of it. For this small test case: moc < --- src/tools/moc/preprocessor.cpp | 26 ++++++++++++++++++-------- src/tools/moc/preprocessor.h | 4 ++-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index 087b064c0f..ff435085b4 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -52,11 +52,12 @@ static QByteArray cleaned(const QByteArray &input) QByteArray result; result.reserve(input.size()); const char *data = input.constData(); + const char *end = input.constData() + input.size(); char *output = result.data(); int newlines = 0; - while (*data) { - while (*data && is_space(*data)) + while (data != end) { + while (data != end && is_space(*data)) ++data; bool takeLine = (*data == '#'); if (*data == '%' && *(data+1) == ':') { @@ -66,15 +67,15 @@ static QByteArray cleaned(const QByteArray &input) if (takeLine) { *output = '#'; ++output; - do ++data; while (*data && is_space(*data)); + do ++data; while (data != end && is_space(*data)); } - while (*data) { + while (data != end) { // handle \\\n, \\\r\n and \\\r if (*data == '\\') { if (*(data + 1) == '\r') { ++data; } - if (*data && (*(data + 1) == '\n' || (*data) == '\r')) { + if (data != end && (*(data + 1) == '\n' || (*data) == '\r')) { ++newlines; data += 1; if (*data != '\r') @@ -964,6 +965,13 @@ int Preprocessor::evaluateCondition() return expression.value(); } +static QByteArray readOrMapFile(QFile *file) +{ + const qint64 size = file->size(); + char *rawInput = reinterpret_cast(file->map(0, size)); + return rawInput ? QByteArray::fromRawData(rawInput, size) : file->readAll(); +} + void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) { currentFilenames.push(filename); @@ -1020,7 +1028,8 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) if (!file.open(QFile::ReadOnly)) continue; - QByteArray input = file.readAll(); + QByteArray input = readOrMapFile(&file); + file.close(); if (input.isEmpty()) continue; @@ -1157,9 +1166,10 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) currentFilenames.pop(); } -Symbols Preprocessor::preprocessed(const QByteArray &filename, QIODevice *file) +Symbols Preprocessor::preprocessed(const QByteArray &filename, QFile *file) { - QByteArray input = file->readAll(); + QByteArray input = readOrMapFile(file); + if (input.isEmpty()) return symbols; diff --git a/src/tools/moc/preprocessor.h b/src/tools/moc/preprocessor.h index fc86781be8..77f3a30ac0 100644 --- a/src/tools/moc/preprocessor.h +++ b/src/tools/moc/preprocessor.h @@ -57,7 +57,7 @@ typedef SubArray MacroName; #endif typedef QHash Macros; -class QIODevice; +class QFile; class Preprocessor : public Parser { @@ -67,7 +67,7 @@ public: QList frameworks; QSet preprocessedIncludes; Macros macros; - Symbols preprocessed(const QByteArray &filename, QIODevice *device); + Symbols preprocessed(const QByteArray &filename, QFile *device); void parseDefineArguments(Macro *m); -- cgit v1.2.3