Feature Request: Expose QPainter methods that accept pointers

Ognyan Moore ognyan.moore at gmail.com
Sat May 28 06:39:39 BST 2022


Hi Phil,

We started doing some benchmarking using the following script:

from PyQt6 import QtCore, QtGui
import PyQt6.sip as sip
import numpy as np

import itertools
from time import perf_counter

class LineSegments:
    def __init__(self, use_sip_array):
        self.use_sip_array = hasattr(sip, 'array') and use_sip_array
        self.alloc(0)

    def alloc(self, size):
        if self.use_sip_array:
            self.objs = sip.array(QtCore.QLineF, size)
            vp = sip.voidptr(self.objs, len(self.objs)*4*8)
            self.arr = np.frombuffer(vp, dtype=np.float64).reshape((-1, 4))
        else:
            self.arr = np.empty((size, 4), dtype=np.float64)
            self.objs = list(map(sip.wrapinstance,
                itertools.count(self.arr.ctypes.data, self.arr.strides[0]),
                itertools.repeat(QtCore.QLineF, self.arr.shape[0])))

    def get(self, size):
        if size != self.arr.shape[0]:
            self.alloc(size)
        return self.objs, self.arr

def run(size, use_sip_array):
    qimg = QtGui.QImage(640, 480, QtGui.QImage.Format.Format_RGB32)
    qimg.fill(QtCore.Qt.GlobalColor.transparent)
    segments = LineSegments(use_sip_array)
    objs, arr = segments.get(size)

    arr[:, 0] = 0
    arr[:, 1] = 0
    arr[:, 2] = qimg.width()
    arr[:, 3] = qimg.height()

    painter = QtGui.QPainter(qimg)
    painter.setPen(QtCore.Qt.GlobalColor.cyan)

    draw_t0 = perf_counter()
    painter.drawLines(objs)
    draw_t1 = perf_counter()

    painter.end()
    return draw_t1 - draw_t0

size = int(1e6)
for use_sip_array in [True, False]:
    dt = run(size, use_sip_array)
    print(f'{use_sip_array=} {dt:.3f}')


Here we noticed that using sip.array was slightly faster than not on macOS,
but on Windows it was slightly slower.  Then when we changed the endpoint
of the line to (10, 10) instead of the width and height of the QImage as
such:

arr[:, 2] = 10
arr[:, 3] = 10

We started seeing significantly higher penalties for using sip.array

On macOS:

use_sip_array=True 0.513
use_sip_array=False 0.171


On Windows:

use_sip_array=True 0.351
use_sip_array=False 0.218


Also for sanity sake, the output of pip list:

Package    Version             Editable project location
---------- ------------------- ------------------------------
numpy      1.22.4
pip        22.1.1
PyQt6      6.3.1.dev2205201737
PyQt6-Qt6  6.3.0
PyQt6-sip  13.4.0
pyqtgraph  0.12.4.dev0         /Users/ogi/Developer/pyqtgraph
setuptools 58.1.0
wheel      0.37.1

Let me know if there is another use case I should test.

Thanks!
Ogi

On Thu, May 26, 2022 at 2:19 PM Phil Thompson <phil at riverbankcomputing.com>
wrote:

> On 26/05/2022 19:46, Ognyan Moore wrote:
> > Hi Phil,
> >
> > Thanks for providing this.  One of our regular contributors just
> > started
> > testing, one issue came up as a compiler failure in
> > PyQt6_sip:sip_array.c
> > line 261 on MSVC, which was fixed by casting to (char*) before doing
> > the
> > pointer arithmetic.
>
> Should be fixed in the next snapshot.
>
> Thanks,
> Phil
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20220527/a437e67b/attachment.htm>


More information about the PyQt mailing list