eri0o
eri0o

Reputation: 2450

PYQT - help profiling python code {built-in method exec_}

I'm developing a software in PyQt to edit tile maps in a game - it has support to lots of things exclusive to my game.

My game mainly has small maps, but I wanted to try doing a bigger map - but unfortunately, my editor seems to be sluggish (at best) with bigger maps - specifically at creation. Each tile in the editor is a label with a image. So I did a 90x90 map on it and used the python profile to understand what was keeping it down.

python -m cProfile Editor.py > profile.log

The lines that reached more than one second in total time are below:

ncalls  tottime percall cumtime percall filename:lineno(function)   
8205    22.397  0.003   22.397  0.003   {built-in   method  show}
1       5.09    5.09    37.913  37.913  {built-in   method  exec_}
1       1.824   1.824   1.824   1.824   {getExistingDirectory}      
1       1.038   1.038   1.038   1.038   {question}      

Ok, so getExistingDirectory takes the time I take to select the directory, so I'm excluding it.

Turns out show gets called 8205 times! since there are 8100 tiles in the map, I think this is related to it - I made a 90x90 map, which is 8100 tiles. At the same time, there are other controls in the screen and even a palette with 117 elements - all other controls probably sum 200 widgets at least.

So the tiles that are in the central widget are created after I click new file. My question is, is there a away so that show, instead of being called once for each label widget, to be called only once for the bigger widget where they are inside?

update:

Turns out I'm calling show myself at creation of each. I removed the calls! Unfortunately, time went up.

ncalls tottime percall cumtime percall filename:lineno(function)
1      43.588  43.588  53.901  53.901  {built-in method exec_}     
1      2.325   2.325   2.325   2.325   {getExistingDirectory}       
1      1.447   1.447   1.447   1.447   {question}       
2      0.265   0.132   1.773   0.887   Editor.py:59(DrawMap)       
8452   0.244   0       0.244   0       {built-in method scaled}     
8442   0.227   0       1.233   0       TileXtra.py:319(initTile)       
24852  0.221   0       0.221   0       {built-in method connect}     
42260  0.128   0       0.128   0       {PIL._imaging.alpha_composite}       
42260  0.077   0       0.115   0       Image.py:472(_new)       
8452   0.077   0       0.24    0       ImageQt.py:44(__init__)       
8452   0.074   0       0.074   0       {fromImage}       
42260  0.072   0       0.403   0       Image.py:2033(alpha_composite)       
1      0.064   0.064   54.158  54.158  Editor.py:3(<module>)       
8452   0.042   0       0.042   0       {method 'encode' of 'ImagingEncoder' objects}   
8452   0.038   0       0.132   0       Image.py:530(tobytes)       
67740  0.036   0       0.05    0       Image.py:628(load)       
24852  0.033   0       0.033   0       {PyQt4.QtCore.SIGNAL}       
42664  0.03    0       0.03    0       Image.py:461(__init__)       

Upvotes: 4

Views: 7388

Answers (1)

eri0o
eri0o

Reputation: 2450

OK found solution.

In the draw method of the widget with multiple widgets, make it hidden then showit in pyqt using QWidget.setVisible (self, bool visible), like:

class BigWidget(QWidget):
    def __init__(self, parent=None, **kwargs):
        QWidget.__init__(self, parent, **kwargs)

        ...

    def DrawManyWidgets(self, parent):
        self.setVisible(False)

        ...

        self.setVisible(True)

Upvotes: 1

Related Questions