Add QStringList::join(QLatin1String) overload

Costs only ~300B in text size in QtCore, which is roughly compensated by
savings in other QtBase libraries, even without specifically porting
users to QL1S.

Of course, the raison d'être for this overload is avoiding the expensive
QLatin1String -> QString conversion which, for small lists, can take up
to 50% of the total runtime (assuming memory allocations dominate over
scanning and copying the list).

[ChangeLog][QtCore][QStringList] Added join(QLatin1String) overload.

Change-Id: I91d7e1d4e2c76d6dc79f2b750cf8e256dd4e0ab6
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2016-08-28 19:23:45 +02:00
parent c52bb03090
commit d58d7a5376
3 changed files with 41 additions and 7 deletions

View File

@ -447,6 +447,17 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegularEx
#endif // QT_NO_REGULAREXPRESSION
#endif // QT_BOOTSTRAPPED
static int accumulatedSize(const QStringList &list, int seplen)
{
int result = 0;
if (!list.isEmpty()) {
for (const auto &e : list)
result += e.size() + seplen;
result -= seplen;
}
return result;
}
/*!
\fn QString QStringList::join(const QString &separator) const
@ -464,15 +475,9 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegularEx
*/
QString QtPrivate::QStringList_join(const QStringList *that, const QChar *sep, int seplen)
{
int totalLength = 0;
const int totalLength = accumulatedSize(*that, seplen);
const int size = that->size();
for (int i = 0; i < size; ++i)
totalLength += that->at(i).size();
if(size > 0)
totalLength += seplen * (size - 1);
QString res;
if (totalLength == 0)
return res;
@ -485,6 +490,27 @@ QString QtPrivate::QStringList_join(const QStringList *that, const QChar *sep, i
return res;
}
/*!
\fn QString QStringList::join(QLatin1String separator) const
\since 5.8
\overload join()
*/
QString QtPrivate::QStringList_join(const QStringList &list, QLatin1String sep)
{
QString result;
if (!list.isEmpty()) {
result.reserve(accumulatedSize(list, sep.size()));
const auto end = list.end();
auto it = list.begin();
result += *it;
while (++it != end) {
result += sep;
result += *it;
}
}
return result;
}
/*!
\fn QStringList QStringList::operator+(const QStringList &other) const

View File

@ -73,6 +73,7 @@ public:
inline int removeDuplicates();
inline QString join(const QString &sep) const;
inline QString join(QLatin1String sep) const;
inline QString join(QChar sep) const;
inline QStringList filter(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
@ -159,6 +160,7 @@ namespace QtPrivate {
void Q_CORE_EXPORT QStringList_sort(QStringList *that, Qt::CaseSensitivity cs);
int Q_CORE_EXPORT QStringList_removeDuplicates(QStringList *that);
QString Q_CORE_EXPORT QStringList_join(const QStringList *that, const QChar *sep, int seplen);
Q_CORE_EXPORT QString QStringList_join(const QStringList &list, QLatin1String sep);
QStringList Q_CORE_EXPORT QStringList_filter(const QStringList *that, const QString &str,
Qt::CaseSensitivity cs);
@ -200,6 +202,11 @@ inline QString QListSpecialMethods<QString>::join(const QString &sep) const
return QtPrivate::QStringList_join(self(), sep.constData(), sep.length());
}
QString QListSpecialMethods<QString>::join(QLatin1String sep) const
{
return QtPrivate::QStringList_join(*self(), sep);
}
inline QString QListSpecialMethods<QString>::join(QChar sep) const
{
return QtPrivate::QStringList_join(self(), &sep, 1);

View File

@ -341,6 +341,7 @@ void tst_QStringList::join() const
QFETCH(QString, expectedResult);
QCOMPARE(input.join(separator), expectedResult);
QCOMPARE(input.join(QLatin1String(separator.toLatin1())), expectedResult);
}
void tst_QStringList::join_data() const