I have modified my application which uses QGraphicsView framework to draw a grid simmilar to yours and I implemented it in a worst possible way:
painter->setPen(p);
for(int row=10+((int)(rect.top())/10)*10; row<rect.bottom(); row+=10){
for(int col = 10+((int)(rect.left())/10)*10; col<rect.right(); col+=10)
painter->drawPoint(col, row);
}
}
void drawBackground ( QPainter * painter, const QRectF & rect ){
static QPen p(QColor(150,150,150));
painter->setPen(p);
for(int row=10+((int)(rect.top())/10)*10; row<rect.bottom(); row+=10){
for(int col = 10+((int)(rect.left())/10)*10; col<rect.right(); col+=10)
painter->drawPoint(col, row);
}
}
To copy to clipboard, switch view to plain text mode
Profiling info (compiled with -fno-inline -ggdb -pg) looks like this:
% cumulative self self total
time seconds seconds calls us/call us/call name
33.33 0.02 0.02 1547664 0.01 0.01 QRectF::right() const
33.33 0.04 0.02 SpecScene::drawBackground(QPainter*, QRectF const&)
16.67 0.05 0.01 1527572 0.01 0.01 QPainter::drawPoint(int, int)
% cumulative self self total
time seconds seconds calls us/call us/call name
33.33 0.02 0.02 1547664 0.01 0.01 QRectF::right() const
33.33 0.04 0.02 SpecScene::drawBackground(QPainter*, QRectF const&)
16.67 0.05 0.01 1527572 0.01 0.01 QPainter::drawPoint(int, int)
To copy to clipboard, switch view to plain text mode
As you see 33% of the application time is spent in drawBackground and half of it is used to calculate QRectF::right() (which makes sense as it gets calculated in each iteration of the loop) and pretty much is used to actually draw the points.
index % time self children called name
<spontaneous>
[1] 83.3 0.02 0.03 SpecScene::drawBackground(QPainter*, QRectF const&) [1]
0.02 0.00 1547627/1547664 QRectF::right() const [2]
0.01 0.00 1527572/1527572 QPainter::drawPoint(int, int) [3]
0.00 0.00 20635/20651 QRectF::bottom() const [35]
0.00 0.00 20055/20055 QRectF::left() const [36]
0.00 0.00 580/580 QRectF::top() const [93]
0.00 0.00 1/702 QColor::QColor(int, int, int, int) [92]
index % time self children called name
<spontaneous>
[1] 83.3 0.02 0.03 SpecScene::drawBackground(QPainter*, QRectF const&) [1]
0.02 0.00 1547627/1547664 QRectF::right() const [2]
0.01 0.00 1527572/1527572 QPainter::drawPoint(int, int) [3]
0.00 0.00 20635/20651 QRectF::bottom() const [35]
0.00 0.00 20055/20055 QRectF::left() const [36]
0.00 0.00 580/580 QRectF::top() const [93]
0.00 0.00 1/702 QColor::QColor(int, int, int, int) [92]
To copy to clipboard, switch view to plain text mode
As you see it is actually more time consuming to calculate the rectangle coords than to draw points!
Some facts:
- I use Qt4.2.2 on i686 Linux,
- I didn't use antialiasing,
- I didn't use scaling (so I have an identity matrix when it comes to viewport-window transformations),
- scene size was about 1200x1000,
- I didn't compile Qt with profiling information (so I guess it's not required after all),
- I got detailed info about both mine and Qt methods,
- the result is pretty fast.
I got a pretty good result, but I didn't suffer from viewport-window transformations which might be your case if you scale the view. I didn't use antialiasing for my view, as points are points - they don't suffer from the aliasing effect. I could easily improve the implementation by calculating rectangle coordinates once per drawBackground() which should reduce the execution effort by half.
It is up to you to do the interpretation of the results. My impression is that it is not really drawBackground() which causes the slowdown - maybe it is just called too often by other parts of the system? Maybe you abuse update()?
Bookmarks