[PyQt] QGraphicsView very slow under Linux and Mac OS X
clemens.brunner at tugraz.at
Fri Apr 5 19:33:59 BST 2013
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?
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...
>> 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.
More information about the PyQt