Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-23756

Inefficient handling of applications with large amount of widgets

    XMLWordPrintable

Details

    Description

      We came across an issue while working on our application that has a large amount of widgets (4500+) and a very slow CPU - arm9 200 Mhz.
      The issue was an incredibly large delays when displaying dialogs. According to our benchmarks, the dialog was spending around 450ms inside the show() method.

      After investigating this issue, the following things were discovered:

      1. allWidgets is a static QSet<QWidget*> , but, to perform iterations on that set, it's first converted (using shallow copy) to a QList, and it's done on every call to allWidgets()
      2. several functions (topLevelWidgets(), enterModal(), etc) use the result of that function inefficiently, causing allWidgets() to be called several times and copied over again and again
      3. topLevelWidgets() is a function that is called every time when dialogs are displayed. It's implementation is unoptimized, it searches the WHOLE list of widgets EVERY time just to find the list of top level widgets.
      4. when a QDialog appears a WindowBlocked event is sent to ALL non-window widgets in the system. (even the hidden ones).

      To handle the 4th issue, we've applied the same conditions used in handling WindowActivated/Deactivated event, i.e. added a "don't forward to hidden widgets" condition.
      You can see our modification in patch named improve_windowBlocked.patch attached. Using this change, we've improved performance of dialog opening from 450ms to 140ms.

      To handle the first 3 issues, two approaches can be used.
      a) Improve topLevelWidgets() function so that it will work directly with allWidgets set and will not require list conversion.
      You can see our modification in patch named improve_topLevel1.patch attached. Using this change, we've improved performance of dialog opening from 140ms to 90ms.
      b) An even better solution would be to maintain a separate QSet of widgets just for the top level ones. This would save us from the iteration and comparison.
      You can see our modification in patch named improve_topLevel2.patch attached. Using this change, we've improved performance of dialog opening from 90ms to 45ms.

      We'd recommend applying both improve_windowBlocked.patch and the improve_topLevel2.patch due to better performance
      If you consider improve_topLevel2.patch too intrusive, even the improve_topLevel1.patch would improve the situation.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            reflog Eli Yukelzon
            reflog Eli Yukelzon
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes