Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qt: Optimize string concatenation by default #313

Merged
merged 2 commits into from
May 26, 2021

Conversation

hebasto
Copy link
Member

@hebasto hebasto commented May 3, 2021

From Qt docs:

... multiple uses of the [QString] '+' operator usually means multiple memory allocations. When concatenating n substrings, where n > 2, there can be as many as n - 1 calls to the memory allocator.

With this PR

... the '+' will automatically be performed as the QStringBuilder '%' everywhere.

The change in the src/Makefile.qt.include file does not justify submitting this PR into the main repo, IMHO.

@hebasto hebasto force-pushed the 210503-builder branch 2 times, most recently from daa63ed to b4e1480 Compare May 3, 2021 10:46
Copy link
Member

@jarolrod jarolrod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK b4e1480 🥃

This simplifies and reduces the mental burden of having to think about "am I concatenating a string in the most efficient way possible?"

I could not find any other occurrences of including QStringBuilder or occurrences of concatenating string with %.

@hebasto
Copy link
Member Author

hebasto commented May 5, 2021

@Talkless

Could you look into this PR?

@Talkless
Copy link

Talkless commented May 5, 2021

It's true that QtCreator, and Qt itself is built with that flag, but we might want to discuss if we want that "implicit magic". There is some caveat with this kind of code:

#include <QString>
#include <QDebug>

QString zoo() {
    return QString{"zoo"};
}

int main()
{
    const auto foo = QString("bar") % QLatin1Char(' ') % zoo();
    qDebug() << foo; // crash because QStringBuilder<T...> expression template will have references to dead temporaries
}

"maybe" it is possible to write similar code and "sometimes" not crash, IDK. Not sure if this is dangerous in any new code, i.e. if it will be missed by reviewers, if it will pass without "sometimes" crashing, etc. Although, we are talking about GUI code, so.. not sure.

I personally still use % for "explicitness", but as @jarolrod said, it removes burned of thinking about inefficient concatenation & stuff... And less annoying nit comments from me :D .

Copy link

@Talkless Talkless left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK

src/qt/optionsmodel.cpp Outdated Show resolved Hide resolved
@@ -114,7 +114,7 @@ QVariant PeerTableModel::data(const QModelIndex &index, int role) const
return (qint64)rec->nodeStats.nodeid;
case Address:
// prepend to peer address down-arrow symbol for inbound connection and up-arrow for outbound connection
return QString(rec->nodeStats.fInbound ? "↓ " : "↑ ") + QString::fromStdString(rec->nodeStats.addrName);
return QString::fromStdString((rec->nodeStats.fInbound ? "↓ " : "↑ ") + rec->nodeStats.addrName);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is motive for this change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qt/peertablemodel.cpp:117:20: error: no viable conversion from returned value of type 'QStringBuilder<typename QConcatenable<QString>::type, typename QConcatenable<QString>::type>' (aka 'QStringBuilder<QString, QString>') to function return type 'QVariant'
            return QString(rec->nodeStats.fInbound ? "↓ " : "↑ ") + QString::fromStdString(rec->nodeStats.addrName);
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/qt/transactiondesc.cpp Outdated Show resolved Hide resolved
@hebasto hebasto changed the title qt, build: Optimize string concatenation by default Optimize string concatenation by default May 9, 2021
@hebasto
Copy link
Member Author

hebasto commented May 15, 2021

@Talkless

It's true that QtCreator, and Qt itself is built with that flag, but we might want to discuss if we want that "implicit magic".

You are right! Discussion is a good mean to reach (rough) consensus about suggested changes.

There is some caveat with this kind of code:

You code snippet could be fixed by s/auto/QString/, and such caveats could be documented in https://github.com/bitcoin-core/bitcoin-devwiki/wiki/Developer-Notes-for-Qt-Code.

The defined QT_USE_QSTRINGBUILDER macro means using the QStringBuilder
for efficient string concatenation in all Qt code by default.
@hebasto
Copy link
Member Author

hebasto commented May 15, 2021

Updated b4e1480 -> a02c970 (pr313.02 -> pr313.03, diff):

@Talkless
Copy link

You code snippet could be fixed by s/auto/QString/

Yes, but that's the "danger", as one needs to know these kinda caveats. Yes, docs could help.

@hebasto hebasto requested a review from maflcko May 19, 2021 18:30
Copy link

@Talkless Talkless left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK a02c970, built successfully on Debian Sid with Qt 5.15.2, but did not check if any displayed strings are "wrong" after refactoring.

Copy link
Member

@jarolrod jarolrod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK a02c970

Tested most of the strings on Qt 5.15.2 macOS 11.3

@laanwj
Copy link
Member

laanwj commented May 26, 2021

Code review ACK a02c970

This simplifies and reduces the mental burden of having to think about "am I concatenating a string in the most efficient way possible?"

I don't think there is any place in bitcoin where concatenating Qt strings is actually a bottleneck, but agree with this perspective.

It's true that QtCreator, and Qt itself is built with that flag,

That's reassuring also in the sense that it probably won't just go away.

@laanwj laanwj changed the title Optimize string concatenation by default qt: Optimize string concatenation by default May 26, 2021
@laanwj laanwj merged commit 456c8d6 into bitcoin-core:master May 26, 2021
@hebasto hebasto deleted the 210503-builder branch May 26, 2021 13:23
@jonatack
Copy link
Member

Approach ACK, this looks like a good idea indeed.

@bitcoin-core bitcoin-core locked as resolved and limited conversation to collaborators Aug 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants