Details
-
Bug
-
Resolution: Done
-
P2: Important
-
None
-
5.9.4, 5.10.1
Description
Hello,
We noticed that using nice convenience methods to build up QPainterPath takes an unproportionally long time when the number of shapes grows, making them practically unusable for drawing some complex paths. Going back to basic QPainterPath::lineTo() and QPainterPath::moveTo() fixes the issue.
According to the source [1], the issue is likely that code forces the underlying vector to allocate exact number of elements as it would be after the addition of a shape, and that destroys the vector's exponential re-allocation strategy.
The similar issue is likely present also for QPainterPath::addRegion(), QPainterPath::addEllipse(), QPainterPath::addRect() and QPainterPath::addRegion().
A test case is attached for QPainterPath::addPolygon(). On Linux, executing run.sh prints the following:
./run.sh + cmake . - Configuring done - Generating done - Build files have been written to: [...] + make [ 25%] Automatic moc for target aexe [ 25%] Built target aexe_automoc [100%] Built target aexe + echo '--- built-in ---' — built-in — + ./aexe builtin 5000 real 0m0,260s user 0m0,068s sys 0m0,188s + ./aexe builtin 10000 real 0m1,001s user 0m0,236s sys 0m0,764s + ./aexe builtin 20000 real 0m4,395s user 0m1,196s sys 0m3,196s + echo '--- workaround ---' — workaround — + ./aexe workaround 5000 real 0m0,006s user 0m0,008s sys 0m0,000s + ./aexe workaround 10000 real 0m0,007s user 0m0,000s sys 0m0,004s + ./aexe workaround 20000 real 0m0,010s user 0m0,004s sys 0m0,004s + ./aexe workaround 10000000 real 0m3,072s user 0m2,268s sys 0m0,800s
We can see that, when adding thousands of polygons using the built-in method, the time grows quadractically. It makes a dramatic difference when adding many polygons to a single QPainterPath - adding 10 million polygons is faster using the workaround than adding 20 thousand polygons using the built-in method.
[1]https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/painting/qpainterpath.cpp#n1074
Attachments
Issue Links
- is duplicated by
-
QTBUG-71707 QVector::reserve() squeezes allocation, can ruin performance on repeated use
- Reported