https://bugs.kde.org/show_bug.cgi?id=524780

--- Comment #8 from [email protected] ---
Created attachment 197421
  --> https://bugs.kde.org/attachment.cgi?id=197421&action=edit
Patch: Avoid copying a whole pivot grid row for every cell read with Qt6

Thanks a lot for looking into this, Ralf. Your QTextBrowser measurements are
right: the renderer really does cost noticeable time, and my original report
was wrong to call it "ruled out".

But it turned out there are TWO SEPARATE PROBLEMS behind the 50-60 s I see.
I tracked down the first one with the help of Claude (an AI assistant), and
a patch for it is attached. I can't judge the C++ details myself, so please
review it carefully.


1) Same code, same file, different result
-----------------------------------------

The nightly Flatpak (master, 2026-10-13, Qt 6.11) with my anonymized file
attached to this bug, report R000183, takes about 60 s on my machine
(i7-1360P), while you get ~8 s. So the difference is the environment, not
the data.


2) Profile of that run
----------------------

gdb sampling with the org.kde.kmymoney.Debug symbols, build IDs verified:

    100.0%  KReportTab::showEvent
     93.4%  reports::PivotTable::renderHTML
     51.8%  QArrayDataPointer<reports::PivotCell>::reallocateAndGrow
     43.1%  QArrayDataPointer<reports::PivotCell>::~QArrayDataPointer
      6.6%  reports::PivotTable::init

(the two QArrayDataPointer entries are called from inside renderHTML)

Almost all of the time was spent building the HTML string. This also
explains why the HTML export was just as slow for me.


3) Cause: QMap::operator[] const changed between Qt5 and Qt6
------------------------------------------------------------

renderHTML() is const and reads every cell twice like this:

    it_row.value()[rowType][column]

- Qt5: "const T QMap::operator[](const Key&) const" returns a const copy.
  [column] then uses the const QList::operator[], so nothing is copied.

- Qt6: "T QMap::operator[](const Key&) const" returns a non-const copy.
  [column] then calls the non-const QList::operator[], which detaches,
  because the data is still shared with the grid. The whole row
  (~871 PivotCells) is deep-copied to read one cell.

The same pattern is used for the totals rows and in renderCSV().

Isolated reproduction (same nested QMap/QList types, 31 x 871 cells):

                  as in renderHTML    with the patch
    Qt 5.15                   3 ms              0 ms
    Qt 6.4                 1486 ms              0 ms

This would also explain why you don't see it, if you build against Qt5.
Is that the case on your openSUSE Leap system?


4) The patch
------------

It adds a const PivotGridRowSet::operator[]() that returns a const
reference to the row. Write access keeps using the inherited non-const
QMap::operator[](), and no call sites need to change (2 files, +22 lines,
nothing removed). The behaviour for a missing row type stays the same: an
empty row is returned.

I used CCBUG: instead of BUG: in the commit message, because it only fixes
one of the two problems.


5) Result in the real application
---------------------------------

I built a Flatpak from current master plus the patch with the repository's
.flatpak-manifest.json (Qt 6.11) and opened the same file and report:

                                nightly (no patch)    with patch
    time to open the report                 ~60 s         ~16 s
    PivotTable::renderHTML                   93 %         1.7 %
    PivotTable::init                        6.6 %        10.2 %
    QTextBrowser (layout etc.)                  -          88 %

So the remaining ~16 s are now almost entirely QTextBrowser, mostly
QTextDocumentLayout with QTextTableCell::firstCursorPosition() on top. That
is the problem you found, and it is independent of this patch. It also
explains why it is still slower than 5.1.3, which used WebEngine.


Side note, in case it is useful: with the Ubuntu 24.04 flatpak-builder
(1.4.2), the manifest fails at glibmm because the meson modules install
into /app/lib64 and pkg-config doesn't find sigc++ there. Adding
-Dlibdir=lib to the meson modules (sigc++, glibmm, libxml++, pcsc-lite)
fixed that for my local build. Newer flatpak-builder versions probably set
this themselves.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to