QTranslator: re-use 'realname' capacity in find_translation()

For almost the whole of its life time, 'realname' has the same
prefix, but the old code used the same string-builder expression
to construct it over and over again. If QStringBuilder would
re-use the capacity of the LHS object, that would boil down to
just a bit more copying of characters than necessary. But
assigning a QStringBuilder expression to a QString works by
implicit conversion of the QStringBuilder expression to a
QString, followed by move-assigning the new QString into the
old.

The new code keeps the common prefix around, resetting
'realname' to that prefix with truncate, only appending the
varying suffixes. In this way, one memory allocation per
assignment is saved (ignoring a potentially required capacity
increase in one of the appends here), and also some out-of-line
QString dtor calls, since op+=(QString&, QStringBuilder...)
doesn't create a temporary QString.

Also saves ~1KiB in text size on optimized GCC 4.9 Linux AMD64
builds.

Change-Id: I0872a69c9111d7218567f06f8fefb010f2430532
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2015-12-27 10:56:38 +01:00
parent 2a2c582306
commit c311815592

View File

@ -634,6 +634,8 @@ static QString find_translation(const QLocale & locale,
}
QString realname;
realname += path + filename + prefix; // using += in the hope for some reserve capacity
const int realNameBaseSize = realname.size();
QStringList fuzzyLocales;
// see http://www.unicode.org/reports/tr35/#LanguageMatching for inspiration
@ -652,14 +654,15 @@ static QString find_translation(const QLocale & locale,
foreach (QString localeName, languages) {
localeName.replace(QLatin1Char('-'), QLatin1Char('_'));
realname = path + filename + prefix + localeName + (suffix.isNull() ? QLatin1String(".qm") : suffix);
realname += localeName + (suffix.isNull() ? QLatin1String(".qm") : suffix);
if (is_readable_file(realname))
return realname;
realname = path + filename + prefix + localeName;
realname.truncate(realNameBaseSize + localeName.size());
if (is_readable_file(realname))
return realname;
realname.truncate(realNameBaseSize);
fuzzyLocales.append(localeName);
}
@ -672,27 +675,35 @@ static QString find_translation(const QLocale & locale,
break;
localeName.truncate(rightmost);
realname = path + filename + prefix + localeName + (suffix.isNull() ? QLatin1String(".qm") : suffix);
realname += localeName + (suffix.isNull() ? QLatin1String(".qm") : suffix);
if (is_readable_file(realname))
return realname;
realname = path + filename + prefix + localeName;
realname.truncate(realNameBaseSize + localeName.size());
if (is_readable_file(realname))
return realname;
realname.truncate(realNameBaseSize);
}
}
const int realNameBaseSizeFallbacks = path.size() + filename.size();
// realname == path + filename + prefix;
if (!suffix.isNull()) {
realname = path + filename + suffix;
realname.replace(realNameBaseSizeFallbacks, prefix.size(), suffix);
// realname == path + filename;
if (is_readable_file(realname))
return realname;
realname.replace(realNameBaseSizeFallbacks, suffix.size(), prefix);
}
realname = path + filename + prefix;
// realname == path + filename + prefix;
if (is_readable_file(realname))
return realname;
realname = path + filename;
realname.truncate(realNameBaseSizeFallbacks);
// realname == path + filename;
if (is_readable_file(realname))
return realname;