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

Performance fixes #2610

Merged
merged 7 commits into from
Jan 30, 2019
Merged

Performance fixes #2610

merged 7 commits into from
Jan 30, 2019

Conversation

brainplot
Copy link
Contributor

Type of change

  • ✅ Bug fix (non-breaking change which fixes an issue)

Description and Context

Just a few more performance improvements spotted thanks to Clang-Tidy and Clazy.

  • Use QFileInfo's exists() static method
    According to the docs, this static method is faster than the instance method of the same class. I simply replaced it accordingly.

  • Replace QMap with QHash when the key is a pointer:
    In a map where the key is a pointer, hash-based lookups are faster than tree-based lookups, as you only have to compute the hash of a number which is an O(1) operation, as opposed to the O(log(n)) complexity of the Red-Black tree of QMaps.

  • Avoid copying QSharedPointers when not needed
    Many QSharedPointers were passed by value even though they did not modify the object pointed to in any way. They have been changed to const QSharedPointer<*>&. Also a few copies were avoided thanks to std::move().
    Actually I took a while to inspect the code a little more carefully and to me it feels like they can all be QScopedPonters or std::unique_ptrs passed by const reference (i.e. without taking ownership) but I didn't want to change that because I thought I may be missing something so I'm just bringing this up for now waiting for your feedback.

  • Avoid creation of temporary containers
    I know we've discussed this already but I couldn't figure out why the static analyzer kept complaining about the creation of temporary containers. It turns out that Qt containers may detach when used as rvalues in a loop. These code examples show that containers must be used as a const lvalue to make sure they won't detach. Basically, by simply storing them in a const variable did the trick in the case of rvalues, using asConst in core/Global.h worked for lvalues; now the static analyzer no longer shows the warnings about temporary containers.
    To prove that, I set up Qt in a local instance of Compiler Explorer and gave it this test code:

#include <QtGlobal>
#include <QMap>
#include <QString>

static const QMap<QString, QString> deprecationMap = {
    // >2.3.4
    {"security/hidepassworddetails", "security/HidePasswordPreviewPanel"},
    // >2.3.4
    {"GUI/HideDetailsView", "GUI/HidePreviewPanel"},
    // >2.3.4
    {"GUI/DetailSplitterState", "GUI/PreviewSplitterState"},
    // >2.3.4
    {"security/IconDownloadFallbackToGoogle", "security/IconDownloadFallback"},
};

void upgrade()
{
    const auto keys = deprecationMap.keys(); // <--
    for (const auto& setting : keys) {
        qWarning("%s\n", setting);
    }
}

The Assembly produced by this was 50 lines shorter than the same code using deprecationMap.keys() in the loop directly. (compiled with gcc -O3)

  • Wrap static literal strings with QStringLiteral
    The QStrings in the deprecation map were implicitly constructed with the const char* constructor which creates a dynamically-allocated string. The map, however, is used in read-only mode and the values are all known at compile time so they can be allocated statically with QStringLiteral.

Testing strategy

I ran all existing tests and they all passed.

Checklist:

  • ✅ I have read the CONTRIBUTING document. [REQUIRED]
  • ✅ My code follows the code style of this project. [REQUIRED]
  • ✅ All new and existing tests passed. [REQUIRED]
  • ✅ I have compiled and verified my code with -DWITH_ASAN=ON. [REQUIRED]

@droidmonkey
Copy link
Member

Can you please rebase this on the newly formatted code. Make sure to run "make format" before you push.

@droidmonkey droidmonkey added this to the v2.4.0 milestone Jan 29, 2019
@brainplot
Copy link
Contributor Author

Done! 👍

Gianluca Recchia added 7 commits January 30, 2019 09:50
The exists() static method is documented to be faster than its
equivalent member method.

See https://doc.qt.io/qt-5/qfileinfo.html#exists-1
QHash gives faster lookups than QMap when the key is a pointer.
The strings in the deprecation map are never modified in the program and
they're known at compile time. An internal resizable buffer is not
needed for these strings so we can allocate them statically.
@droidmonkey droidmonkey merged commit 7f3ce65 into keepassxreboot:develop Jan 30, 2019
@brainplot brainplot deleted the performance-fixes branch January 30, 2019 17:06
droidmonkey added a commit that referenced this pull request Mar 19, 2019
- New Database Wizard [#1952]
- Advanced Search [#1797]
- Automatic update checker [#2648]
- KeeShare database synchronization [#2109, #1992, #2738, #2742, #2746, #2739]
- Improve favicon fetching; transition to Duck-Duck-Go [#2795, #2011, #2439]
- Remove KeePassHttp support [#1752]
- CLI: output info to stderr for easier scripting [#2558]
- CLI: Add --quiet option [#2507]
- CLI: Add create command [#2540]
- CLI: Add recursive listing of entries [#2345]
- CLI: Fix stdin/stdout encoding on Windows [#2425]
- SSH Agent: Support OpenSSH for Windows [#1994]
- macOS: TouchID Quick Unlock [#1851]
- macOS: Multiple improvements; include CLI in DMG [#2165, #2331, #2583]
- Linux: Prevent Klipper from storing secrets in clipboard [#1969]
- Linux: Use polling based file watching for NFS [#2171]
- Linux: Enable use of browser plugin in Snap build [#2802]
- TOTP QR Code Generator [#1167]
- High-DPI Scaling for 4k screens [#2404]
- Make keyboard shortcuts more consistent [#2431]
- Warn user if deleting referenced entries [#1744]
- Allow toolbar to be hidden and repositioned [#1819, #2357]
- Increase max allowed database timeout to 12 hours [#2173]
- Password generator uses existing password length by default [#2318]
- Improve alert message box button labels [#2376]
- Show message when a database merge makes no changes [#2551]
- Browser Integration Enhancements [#1497, #2253, #1904, #2232, #1850, #2218, #2391, #2396, #2542, #2622, #2637, #2790]
- Overall Code Improvements [#2316, #2284, #2351, #2402, #2410, #2419, #2422, #2443, #2491, #2506, #2610, #2667, #2709, #2731]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants