[PyQt] QGraphicsView very slow under Linux and Mac OS X
Clemens Brunner
clemens.brunner at tugraz.at
Thu Jul 18 10:10:25 BST 2013
Hi!
I investigated the problem a bit more, and it seems like it occurs only when I'm running KDE -- in Gnome, everything works as expected (the difference is 1). Since it is now working on both Windows, Mac OS X, and non-KDE systems, it is probably related to KDE (maybe the window manager). Funny though, since KDE is based on Qt :-).
So if anyone running KDE wants to confirm the problem, I've attached the test program again.
Concerning the C++ version, the problem is also there on KDE, only you don't see it when just looking at the timer intervals (because they're always 25ms irrespective of the window size). However, the exposedRect on KDE is still wrong, so I assume that the C++ is just a lot faster so that performance is not (yet) affected in my example.
Clemens
-------------- next part --------------
A non-text attachment was scrubbed...
Name: graphicsviewtest.py
Type: text/x-python-script
Size: 1896 bytes
Desc: not available
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20130718/4a6f6f65/attachment.bin>
-------------- next part --------------
On 04/05/2013 08:33 PM, Clemens Brunner wrote:
> Hi!
>
> I think I found the problem: https://bugreports.qt-project.org/browse/QTBUG-13573
>
> The exposedRect returns the whole window width on Linux and Mac OS X, whereas it correctly returns only the area that needs to be updated on Windows.
>
> To illustrate this, just add the following line to my example code within the paint() function just before the for loop:
>
> print int(option.exposedRect.right()) - int(option.exposedRect.left())
>
> On Windows, this is always 1, as expected. On Linux, this corresponds to the window width.
>
> This bug explains why it is so damn slow. However, it doesn't seem to occur on all Linux platforms, since you guys get timer intervals as expected. Maybe you want to check the output of the print statement above, but I assume it is 1 on your platform. Which leads me to the question: how can we fix this bug? Or is there at least a workaround?
>
> I suspect that it might have something to do with the Intel graphics chip, which I have in both my Linux and Mac machine.
>
> [Update:] I just tested the behavior on my Mac again: in the first second, I get the whole width for the exposedRect and large timer intervals (and therefore slow performance). However, after about a second, I get the correct value of 1, because Mac OS X switches from the Intel onboard chip to the nVidia graphics chip. This is just a speculation, because disabling graphics switching (which should permanently enable the nVidia chip) yields the same behavior. Strangely though, it does work on my Mac now after this initial second (maybe some updated got installed that fixed the problem?).
>
> Any more ideas?
>
> Clemens
>
>
>
> On Apr 4, 2013, at 17:15 , Clemens Brunner <clemens.brunner at tugraz.at> wrote:
>
>> On 04/03/2013 06:46 PM, Hans-Peter Jansen wrote:
>>
>>> Which graphic driver do you use? (that doesn't tell us much, since the C++
>>> version behave with the same driver, just for the record..)
>>
>> xf86-video-intel 2.21.5-1
>> intel-dri 9.1.1-1
>>
>>> Might be worth to compare the C++ version (that you should publish here?)
>>> and the Python versions with perf. Of course, they differ...
>>
>> Attached.
>>
>>> python versions, perf running for about 10 sec.
>>>
>>> QT_GRAPHICSSYSTEM=raster perf record -f python graphicsviewtest.py
>>>
>>> [...]
>>>
>>>
>>> QT_GRAPHICSSYSTEM=opengl perf record -f python graphicsviewtest.py
>>>
>>> [...]
>>>
>>>
>>> The former looks nice, it's a great example, why PyQt rocks. The hottest
>>> areas are there, where they should be: down under, moving bits. Great.
>>>
>>> But the latter looks strange indeed.
>>>
>>> Phil, do you have any idea, why PyEval_EvalFrameEx is the top sucker in
>>> this scenario? This looks, like in opengl mode, it is evaluating some
>>> python expression in its hottest path (data type conversions or the like?).
>>
>> My raster perf report doesn't look nice at all:
>>
>> 14.30% python2 libpython2.7.so.1.0 [.] PyEval_EvalFrameEx
>> 9.39% python2 libQtGui.so.4.8.4 [.] 0x00000000001bf673
>> 8.99% python2 sip.so [.] 0x000000000000b086
>> 6.10% python2 libpython2.7.so.1.0 [.] lookdict_string
>> 4.02% python2 libpython2.7.so.1.0 [.] PyDict_GetItem
>> 3.94% python2 libpython2.7.so.1.0 [.] _PyType_Lookup
>> 3.01% python2 libm-2.17.so [.] 0x00000000000105e0
>> 2.27% python2 libm-2.17.so [.] feraiseexcept
>> 2.23% python2 libpython2.7.so.1.0 [.] _PyObject_GenericGetAttrWithDict
>> 1.71% python2 libpython2.7.so.1.0 [.] binary_op1
>> 1.50% python2 libpython2.7.so.1.0 [.] PyType_IsSubtype
>> 1.40% python2 libpython2.7.so.1.0 [.] PyErr_Restore
>> 1.33% python2 QtGui.so [.] 0x000000000036120b
>> 1.27% python2 libpython2.7.so.1.0 [.] PyObject_Malloc
>> 1.19% python2 libc-2.17.so [.] malloc
>>
>> Same thing but even worse with opengl:
>>
>> 15.49% python2 i965_dri.so [.] 0x000000000003ae99
>> 6.08% python2 libpython2.7.so.1.0 [.] PyEval_EvalFrameEx
>> 5.96% python2 libdrm_intel.so.1.0.0 [.] 0x0000000000007468
>> 5.60% python2 libQtOpenGL.so.4.8.4 [.] 0x0000000000031262
>> 4.96% python2 sip.so [.] 0x000000000000b055
>> 4.32% python2 libdricore9.1.1.so.1.0.0 [.] 0x00000000001ea2b4
>> 2.76% python2 libpython2.7.so.1.0 [.] lookdict_string
>> 2.11% python2 libpython2.7.so.1.0 [.] PyDict_GetItem
>> 1.95% python2 libpython2.7.so.1.0 [.] _PyType_Lookup
>> 1.42% python2 libm-2.17.so [.] 0x00000000000105c0
>> 1.32% python2 libc-2.17.so [.] __memcmp_sse4_1
>> 1.03% python2 libc-2.17.so [.] _int_malloc
>> 1.01% python2 libm-2.17.so [.] feraiseexcept
>> 0.93% python2 libc-2.17.so [.] __memcpy_ssse3_back
>>
>> In both cases, PyEval_EvalFrameEx is at or near the top, and so are other Python things.
>>
>> For the sake of completeness, here's the perf output for the C++ version (which runs perfectly):
>>
>> 43.56% graphicsviewtes libQtGui.so.4.8.4 [.] 0x00000000001c0bb2 q
>> 20.58% graphicsviewtes libm-2.17.so [.] feraiseexcept
>> 15.48% graphicsviewtes libm-2.17.so [.] 0x0000000000015622
>> 4.47% graphicsviewtes graphicsviewtest [.] SignalItem::paint(QPainter*, QStyleOptionGraphicsItem
>> 3.09% graphicsviewtes libQtGui.so.4.8.4 [.] QPen::dashPattern() const
>> 1.17% graphicsviewtes libQtGui.so.4.8.4 [.] QTransform::map(QPointF const&) const
>> 0.77% graphicsviewtes libc-2.17.so [.] free
>> 0.72% graphicsviewtes libQtGui.so.4.8.4 [.] QPainter::drawLines(QLine const*, int)
>> 0.46% graphicsviewtes libpthread-2.17.so [.] __pthread_mutex_unlock_usercnt
>> 0.45% graphicsviewtes libpthread-2.17.so [.] pthread_mutex_lock
>>
>> I tested this program on openSUSE (in a VirtualBox), and in contrast to Vincent, it doesn't work for me there either (same behavior as in my native Arch Linux). BTW, I use KDE and not Gnome, but I doubt that this is relevant. Furthermore, I still have the same bad behavior on my Mac.
>>
>> Clemens
>> <graphicsviewtest.cpp><graphicsviewtest.pro>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: graphicsviewtest.py
Type: text/x-python
Size: 1839 bytes
Desc: not available
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20130718/4a6f6f65/attachment.py>
More information about the PyQt
mailing list