From b11421394b4745253a046461234906feb9c811dc Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Wed, 20 Jul 2016 14:23:59 +0300 Subject: Qml: optimize string usage Use QStringBuilder more. Use QString::asprintf instead of arg()'s chain. Use += operator to reserve extra capacity for possible free following append/prepend/+= call. Change-Id: Ib65398b91566994339d2c4bbfaf94e49806b7471 Reviewed-by: Shawn Rutledge --- src/qml/qml/qqmlbinding.cpp | 14 ++++++-------- src/qml/qml/qqmlboundsignal.cpp | 4 ++-- src/qml/qml/qqmlerror.cpp | 4 ++-- src/qml/qml/qqmlimport.cpp | 23 ++++++++--------------- src/qml/qml/qqmlproperty.cpp | 6 +----- src/qml/qml/qqmlpropertycache.cpp | 4 +++- src/qml/qml/qqmltypeloader.cpp | 13 +++++++------ src/qml/qml/qqmlvaluetype.cpp | 6 +++--- src/qml/qml/qqmlvaluetypewrapper.cpp | 3 ++- src/qml/qml/qqmlvmemetaobject.cpp | 8 ++++---- src/qml/qml/qqmlxmlhttprequest.cpp | 4 ++-- src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 12 ++++++------ 12 files changed, 46 insertions(+), 55 deletions(-) diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 72c7347a68..3b3e23c891 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -378,12 +378,11 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core, QJSValue(QV8Engine::getV4(v8engine), result.asReturnedValue())), context(), flags); } else if (isUndefined) { - QString errorStr = QLatin1String("Unable to assign [undefined] to "); - if (!QMetaType::typeName(type)) - errorStr += QLatin1String("[unknown property type]"); - else - errorStr += QLatin1String(QMetaType::typeName(type)); - delayedError()->setErrorDescription(errorStr); + const QLatin1String typeName(QMetaType::typeName(type) + ? QMetaType::typeName(type) + : "[unknown property type]"); + delayedError()->setErrorDescription(QLatin1String("Unable to assign [undefined] to ") + + typeName); return false; } else if (const QV4::FunctionObject *f = result.as()) { if (f->isBinding()) @@ -458,8 +457,7 @@ QString QQmlBinding::expressionIdentifier() QString url = function->sourceFile(); quint16 lineNumber = function->compiledFunction->location.line; quint16 columnNumber = function->compiledFunction->location.column; - - return url + QLatin1Char(':') + QString::number(lineNumber) + QLatin1Char(':') + QString::number(columnNumber); + return url + QString::asprintf(":%u:%u", uint(lineNumber), uint(columnNumber)); } void QQmlBinding::expressionChanged() diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index ef837183db..4e63790290 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -80,8 +80,8 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, // Add some leading whitespace to account for the binding's column offset. // It's 2 off because a, we start counting at 1 and b, the '(' below is not counted. - function.fill(QChar(QChar::Space), qMax(column, (quint16)2) - 2); - function += QLatin1String("(function ") + handlerName + QLatin1Char('('); + function += QString(qMax(column, (quint16)2) - 2, QChar(QChar::Space)) + + QLatin1String("(function ") + handlerName + QLatin1Char('('); if (parameterString.isEmpty()) { QString error; diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp index 74ceeabeb4..b309550ca8 100644 --- a/src/qml/qml/qqmlerror.cpp +++ b/src/qml/qml/qqmlerror.cpp @@ -249,9 +249,9 @@ QString QQmlError::toString() const int l(line()); if (u.isEmpty() || (u.isLocalFile() && u.path().isEmpty())) - rv = QLatin1String(""); + rv += QLatin1String(""); else - rv = u.toString(); + rv += u.toString(); if (l != -1) { rv += QLatin1Char(':') + QString::number(l); diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 6396ad0bab..63e8da3aa8 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -538,10 +538,10 @@ QString QQmlImports::versionString(int vmaj, int vmin, ImportVersion version) { if (version == QQmlImports::FullyVersioned) { // extension with fully encoded version number (eg. MyModule.3.2) - return QString(QLatin1String(".%1.%2")).arg(vmaj).arg(vmin); + return QString::asprintf(".%d.%d", vmaj, vmin); } else if (version == QQmlImports::PartiallyVersioned) { // extension with encoded version major (eg. MyModule.3) - return QString(QLatin1String(".%1")).arg(vmaj); + return QString::asprintf(".%d", vmaj); } // else extension without version number (eg. MyModule) return QString(); } @@ -1393,15 +1393,9 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix // The uri for this import. For library imports this is the same as uri // specified by the user, but it may be different in the case of file imports. QString importUri = uri; - - QString qmldirPath = importUri; - if (importUri.endsWith(Slash)) - qmldirPath += String_qmldir; - else - qmldirPath += Slash_qmldir; - - QString qmldirUrl = resolveLocalUrl(base, qmldirPath); - + QString qmldirUrl = resolveLocalUrl(base, importUri + (importUri.endsWith(Slash) + ? String_qmldir + : Slash_qmldir)); QString qmldirIdentifier; if (QQmlFile::isLocalFile(qmldirUrl)) { @@ -1699,10 +1693,9 @@ QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader, if (!resolvedPath.endsWith(Slash)) resolvedPath += Slash; + resolvedPath += prefix + baseName; foreach (const QString &suffix, suffixes) { - QString pluginFileName = prefix + baseName + suffix; - - QString absolutePath = typeLoader->absoluteFilePath(resolvedPath + pluginFileName); + const QString absolutePath = typeLoader->absoluteFilePath(resolvedPath + suffix); if (!absolutePath.isEmpty()) return absolutePath; } @@ -1955,7 +1948,7 @@ bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &ba #ifndef QT_NO_LIBRARY // Dynamic plugins are differentiated by their filepath. For static plugins we // don't have that information so we use their address as key instead. - QString uniquePluginID = QString().sprintf("%p", instance); + const QString uniquePluginID = QString::asprintf("%p", instance); StringRegisteredPluginMap *plugins = qmlEnginePluginsWithRegisteredTypes(); QMutexLocker lock(&plugins->mutex); diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index ffa9bfa3a7..e287b68385 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -644,15 +644,11 @@ QString QQmlProperty::name() const // ### if (!d->object) { } else if (d->isValueType()) { - QString rv = d->core.name(d->object) + QLatin1Char('.'); - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d->core.propType); Q_ASSERT(valueTypeMetaObject); const char *vtName = valueTypeMetaObject->property(d->valueTypeData.coreIndex).name(); - rv += QString::fromUtf8(vtName); - - d->nameCache = rv; + d->nameCache = d->core.name(d->object) + QLatin1Char('.') + QString::fromUtf8(vtName); } else if (type() & SignalProperty) { QString name = QLatin1String("on") + d->core.name(d->object); name[2] = name.at(2).toUpper(); diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 71b3fd8309..38fddc8253 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -1195,7 +1195,9 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder) if (data->propType != 0) returnType = QMetaType::typeName(data->propType); - QByteArray signature = methods.at(ii).first.toUtf8() + '('; + QByteArray signature; + // '+=' reserves extra capacity. Follow-up appending will be probably free. + signature += methods.at(ii).first.toUtf8() + '('; QQmlPropertyCacheMethodArguments *arguments = 0; if (data->hasArguments()) { diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index b7154625ee..a151f50a00 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2534,13 +2534,13 @@ void QQmlTypeData::resolveTypes() ScriptReference ref; //ref.location = ... - ref.qualifier = script.nameSpace; if (!script.qualifier.isEmpty()) { - ref.qualifier.prepend(script.qualifier + QLatin1Char('.')); - + ref.qualifier = script.qualifier + QLatin1Char('.') + script.nameSpace; // Add a reference to the enclosing namespace m_namespaces.insert(script.qualifier); + } else { + ref.qualifier = script.nameSpace; } ref.script = blob; @@ -2550,12 +2550,13 @@ void QQmlTypeData::resolveTypes() // Lets handle resolved composite singleton types foreach (const QQmlImports::CompositeSingletonReference &csRef, m_importCache.resolvedCompositeSingletons()) { TypeReference ref; - QString typeName = csRef.typeName; - + QString typeName; if (!csRef.prefix.isEmpty()) { - typeName.prepend(csRef.prefix + QLatin1Char('.')); + typeName = csRef.prefix + QLatin1Char('.') + csRef.typeName; // Add a reference to the enclosing namespace m_namespaces.insert(csRef.prefix); + } else { + typeName = csRef.typeName; } int majorVersion = csRef.majorVersion > -1 ? csRef.majorVersion : -1; diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index eefe7a5fb8..bcefad0ee3 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -260,7 +260,7 @@ int QQmlValueType::metaCall(QObject *, QMetaObject::Call type, int _id, void **a QString QQmlPointFValueType::toString() const { - return QString(QLatin1String("QPointF(%1, %2)")).arg(v.x()).arg(v.y()); + return QString::asprintf("QPointF(%g, %g)", v.x(), v.y()); } qreal QQmlPointFValueType::x() const @@ -307,7 +307,7 @@ void QQmlPointValueType::setY(int y) QString QQmlSizeFValueType::toString() const { - return QString(QLatin1String("QSizeF(%1, %2)")).arg(v.width()).arg(v.height()); + return QString::asprintf("QSizeF(%g, %g)", v.width(), v.height()); } qreal QQmlSizeFValueType::width() const @@ -353,7 +353,7 @@ void QQmlSizeValueType::setHeight(int h) QString QQmlRectFValueType::toString() const { - return QString(QLatin1String("QRectF(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.width()).arg(v.height()); + return QString::asprintf("QRectF(%g, %g, %g, %g)", v.x(), v.y(), v.width(), v.height()); } qreal QQmlRectFValueType::x() const diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index 3ad53aa3fc..c4008d2a05 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -332,7 +332,8 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx) if (QMetaType::convert(w->d()->gadgetPtr, w->d()->valueType->typeId, &convertResult, QMetaType::QString)) { result = convertResult; } else { - result = QString::fromUtf8(QMetaType::typeName(w->d()->valueType->typeId)) + QLatin1Char('('); + result += QString::fromUtf8(QMetaType::typeName(w->d()->valueType->typeId)) + + QLatin1Char('('); const QMetaObject *mo = w->d()->propertyCache->metaObject(); const int propCount = mo->propertyCount(); for (int i = 0; i < propCount; ++i) { diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 81bc6846e6..47c125355b 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -932,10 +932,10 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * // are not rewritten correctly but this bug is deemed out-of-scope to fix for // performance reasons; see QTBUG-24064) and thus compilation will have failed. QQmlError e; - e.setDescription(QString::fromLatin1("Exception occurred during compilation of " - "function: %1") - .arg(QString::fromUtf8(QMetaObject::method(_id) - .methodSignature()))); + e.setDescription(QLatin1String("Exception occurred during compilation of " + "function: ") + + QString::fromUtf8(QMetaObject::method(_id) + .methodSignature())); ep->warning(e); return -1; // The dynamic method with that id is not available. } diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 14c12c2542..58ffab9ec9 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1162,8 +1162,8 @@ QString QQmlXMLHttpRequest::headers() const foreach (const HeaderPair &header, m_headersList) { if (ret.length()) ret.append(QLatin1String("\r\n")); - ret = ret % QString::fromUtf8(header.first) % QLatin1String(": ") - % QString::fromUtf8(header.second); + ret += QString::fromUtf8(header.first) + QLatin1String(": ") + + QString::fromUtf8(header.second); } return ret; } diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index db0439ab9e..fd36f76d0e 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1057,7 +1057,9 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx) struct Error { static ReturnedValue create(QV4::ExecutionEngine *v4, const QList &errors) { Scope scope(v4); - QString errorstr = QLatin1String("Qt.createQmlObject(): failed to create object: "); + QString errorstr; + // '+=' reserves extra capacity. Follow-up appending will be probably free. + errorstr += QLatin1String("Qt.createQmlObject(): failed to create object: "); QV4::ScopedArrayObject qmlerrors(scope, v4->newArrayObject()); QV4::ScopedObject qmlerror(scope); @@ -1497,15 +1499,13 @@ static QV4::ReturnedValue writeToConsole(ConsoleLogTypes logType, CallContext *c result.append(QLatin1Char(' ')); if (ctx->args()[i].as()) - result.append(QLatin1Char('[') + ctx->args()[i].toQStringNoThrow() + QLatin1Char(']')); + result += QLatin1Char('[') + ctx->args()[i].toQStringNoThrow() + QLatin1Char(']'); else result.append(ctx->args()[i].toQStringNoThrow()); } - if (printStack) { - result.append(QLatin1Char('\n')); - result.append(jsStack(v4)); - } + if (printStack) + result += QLatin1Char('\n') + jsStack(v4); static QLoggingCategory qmlLoggingCategory("qml"); static QLoggingCategory jsLoggingCategory("js"); -- cgit v1.2.3