WX python увеличение продолжительности MainL oop - PullRequest
0 голосов
/ 09 марта 2020

Ранее я опубликовал аналогичный вопрос Q, но я удалил его и воспроизвел проблему в гораздо более простой программе, которую я собираюсь опубликовать здесь, чтобы, надеюсь, кто-то еще мог воспроизвести проблему и помочь мне найти решение.

Я использую wx Python с настроенным MainL oop, и проблема в том, что со временем время выполнения определенной инструкции увеличивается, и я понятия не имею, почему. Я нашел пример того, как настроить MainL oop на https://github.com/wxWidgets/wxPython-Classic/blob/master/samples/mainloop/mainloop.py

Программа предназначена для чтения изображений из большого каталога со многими скриншотами, сохраненными в последовательности, до 20 000 , Каждая итерация MainL oop должна переходить к новому изображению в директории. На каждой итерации изображение устанавливается в качестве фона на панели wx python. В этом примере я упростил это, чтобы просто прочитать одно изображение из пути на ini, а затем постоянно устанавливать bg панели wx Python для этого изображения на каждой итерации, вместо того, чтобы читать много изображений последовательно.

Проблема в том, что время выполнения блока кода внутри класса панели быстро увеличивается с течением времени, той части, которая задает это фоновое изображение панели. Кажется, что время выполнения этого блока увеличивается на 15 мсек каждый раз после 20 итераций. Вот код для моей программы. Это может быть легко воспроизведено, все, что вам нужно сделать, это изменить путь img на какой-нибудь img на вашем компьютере.

import time
import os
import gc
import wx

# APP
class MyApp(wx.App):

    def __init__(self):

        self.img_file_path = 'your_path.png'

        super().__init__(clearSigInt=True)

    def MainLoop(self):

        evtloop = wx.GUIEventLoop()
        #old = wx.EventLoop.GetActive()
        wx.EventLoop.SetActive(evtloop)

        while self.keepGoing:

            # this is the only instruction in the customized main loop that I added,
            # everything else is straight out of the example
            self.frame.panel.set_background_image_to_ss(self.img_file_path)

            while evtloop.Pending():
                evtloop.Dispatch()

            # i also changed the sleep from 0.1s in the example to 0.03.
            # either way the execution time increases over time.
            time.sleep(0.03)

            evtloop.ProcessIdle()

        wx.EventLoop.SetActive(old)


    def OnInit(self):

        self.frame = MyFrame(self)
        self.frame.Show(True)

        self.SetTopWindow(self.frame)

        self.keepGoing = True
        return True

# FRAME
class MyFrame(wx.Frame):

    def __init__(self, app_obj, title="CM1", pos=(100, 100), size=(760,800)):

        super().__init__(None, title=title, pos=pos, size=wx.Size(size))

        self.init_panel(app_obj)

    def init_panel(self, app_obj):

        self.panel = MyPanel(self, app_obj)

# PANEL            
class MyPanel(wx.Panel):

    def __init__(self, parent, app_obj):

        super().__init__(parent=parent)

        self.app_obj = app_obj

        self.bg_img = -1

    # PROBLEM METHOD 
    def set_background_image_to_ss(self, path):

        bmp1 = wx.Image(path, wx.BITMAP_TYPE_ANY).ConvertToBitmap()

        # I'm benchmarking the execution time of the following if/else statement
        # for some reason this increases over time
        curr_milliseconds_loop = time.time() * 1000

        if self.bg_img == -1:
            self.bitmap1 = wx.StaticBitmap(self, -1, bmp1, (0, 0))
        else:
            self.bitmap1.Destroy()
            self.bitmap1.SetBitmap(wx.Bitmap(path))

        print("SET BG BITMAP MS=", time.time() * 1000 - curr_milliseconds_loop)


app = MyApp()
app.MainLoop()

, и вот некоторые результаты, полученные в терминале для первых 100 итераций:

SET BG BITMAP MS= 15.666748046875
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 15.400390625
SET BG BITMAP MS= 15.609619140625
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 15.399658203125
SET BG BITMAP MS= 15.40478515625
SET BG BITMAP MS= 15.408203125
SET BG BITMAP MS= 15.404296875
SET BG BITMAP MS= 15.400390625
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 15.4013671875
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 16.65966796875
SET BG BITMAP MS= 15.408935546875
SET BG BITMAP MS= 15.398193359375
SET BG BITMAP MS= 15.401611328125
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 15.589111328125
SET BG BITMAP MS= 0.0
SET BG BITMAP MS= 15.52734375
SET BG BITMAP MS= 15.4091796875
SET BG BITMAP MS= 15.39404296875
SET BG BITMAP MS= 15.388671875
SET BG BITMAP MS= 15.382080078125
SET BG BITMAP MS= 15.400390625
SET BG BITMAP MS= 31.01318359375
SET BG BITMAP MS= 15.3837890625
SET BG BITMAP MS= 15.407958984375
SET BG BITMAP MS= 15.37744140625
SET BG BITMAP MS= 15.6201171875
SET BG BITMAP MS= 15.388916015625
SET BG BITMAP MS= 15.400146484375
SET BG BITMAP MS= 15.401611328125
SET BG BITMAP MS= 15.388427734375
SET BG BITMAP MS= 15.61328125
SET BG BITMAP MS= 15.61474609375
SET BG BITMAP MS= 15.537841796875
SET BG BITMAP MS= 15.378662109375
SET BG BITMAP MS= 15.5322265625
SET BG BITMAP MS= 15.625732421875
SET BG BITMAP MS= 15.623779296875
SET BG BITMAP MS= 15.376708984375
SET BG BITMAP MS= 15.40576171875
SET BG BITMAP MS= 15.56689453125
SET BG BITMAP MS= 15.4033203125
SET BG BITMAP MS= 15.41259765625
SET BG BITMAP MS= 15.607666015625
SET BG BITMAP MS= 15.623291015625
SET BG BITMAP MS= 15.621826171875
SET BG BITMAP MS= 15.5947265625
SET BG BITMAP MS= 15.5625
SET BG BITMAP MS= 15.5693359375
SET BG BITMAP MS= 15.62109375
SET BG BITMAP MS= 31.192138671875
SET BG BITMAP MS= 31.173828125
SET BG BITMAP MS= 31.23779296875
SET BG BITMAP MS= 31.18017578125
SET BG BITMAP MS= 15.62060546875
SET BG BITMAP MS= 15.563720703125
SET BG BITMAP MS= 15.61083984375
SET BG BITMAP MS= 31.21728515625
SET BG BITMAP MS= 31.23828125
SET BG BITMAP MS= 31.23486328125
SET BG BITMAP MS= 31.23779296875
SET BG BITMAP MS= 31.23583984375
SET BG BITMAP MS= 31.236572265625
SET BG BITMAP MS= 31.23388671875
SET BG BITMAP MS= 31.23876953125
SET BG BITMAP MS= 31.27392578125
SET BG BITMAP MS= 31.236083984375
SET BG BITMAP MS= 31.23876953125
SET BG BITMAP MS= 31.18408203125
SET BG BITMAP MS= 31.235107421875
SET BG BITMAP MS= 15.621337890625
SET BG BITMAP MS= 15.616943359375
SET BG BITMAP MS= 15.62353515625
SET BG BITMAP MS= 15.62255859375
SET BG BITMAP MS= 15.62353515625
SET BG BITMAP MS= 15.622802734375
SET BG BITMAP MS= 15.619873046875
SET BG BITMAP MS= 31.2353515625
SET BG BITMAP MS= 31.229248046875
SET BG BITMAP MS= 31.2265625
SET BG BITMAP MS= 31.226806640625
SET BG BITMAP MS= 31.14990234375
SET BG BITMAP MS= 31.271728515625
SET BG BITMAP MS= 31.23095703125
SET BG BITMAP MS= 31.229736328125
SET BG BITMAP MS= 31.273193359375
SET BG BITMAP MS= 31.2353515625
SET BG BITMAP MS= 31.194091796875
SET BG BITMAP MS= 31.235107421875
SET BG BITMAP MS= 31.23828125
SET BG BITMAP MS= 31.232421875
SET BG BITMAP MS= 31.2373046875
SET BG BITMAP MS= 31.23291015625
SET BG BITMAP MS= 31.2353515625
SET BG BITMAP MS= 31.236572265625
SET BG BITMAP MS= 31.235107421875
SET BG BITMAP MS= 31.231201171875
SET BG BITMAP MS= 31.239501953125
SET BG BITMAP MS= 31.2041015625
SET BG BITMAP MS= 31.238525390625
SET BG BITMAP MS= 31.231201171875
SET BG BITMAP MS= 31.231201171875
SET BG BITMAP MS= 31.2314453125
SET BG BITMAP MS= 31.2333984375
SET BG BITMAP MS= 31.19775390625
SET BG BITMAP MS= 31.22412109375
SET BG BITMAP MS= 31.2421875
SET BG BITMAP MS= 46.819580078125
SET BG BITMAP MS= 46.85400390625
SET BG BITMAP MS= 46.846435546875
SET BG BITMAP MS= 31.23193359375
SET BG BITMAP MS= 46.853759765625
SET BG BITMAP MS= 31.2265625
SET BG BITMAP MS= 46.853759765625
SET BG BITMAP MS= 46.85595703125
SET BG BITMAP MS= 46.84912109375
SET BG BITMAP MS= 46.844970703125
SET BG BITMAP MS= 46.85107421875
SET BG BITMAP MS= 46.8525390625
SET BG BITMAP MS= 46.853271484375
SET BG BITMAP MS= 46.845703125
SET BG BITMAP MS= 46.794921875
SET BG BITMAP MS= 46.889404296875
SET BG BITMAP MS= 46.845458984375
SET BG BITMAP MS= 46.851806640625
SET BG BITMAP MS= 46.841064453125
SET BG BITMAP MS= 46.849853515625
SET BG BITMAP MS= 46.85107421875
SET BG BITMAP MS= 31.239501953125
SET BG BITMAP MS= 46.842529296875
SET BG BITMAP MS= 46.8466796875
SET BG BITMAP MS= 46.846435546875
SET BG BITMAP MS= 46.841064453125
SET BG BITMAP MS= 46.8544921875
SET BG BITMAP MS= 46.818603515625
SET BG BITMAP MS= 46.843017578125
SET BG BITMAP MS= 46.89453125
SET BG BITMAP MS= 46.789306640625
SET BG BITMAP MS= 46.848388671875
SET BG BITMAP MS= 46.843994140625
SET BG BITMAP MS= 46.8505859375
SET BG BITMAP MS= 46.849609375
SET BG BITMAP MS= 46.8486328125
SET BG BITMAP MS= 46.841796875
SET BG BITMAP MS= 46.89404296875
SET BG BITMAP MS= 46.79248046875
SET BG BITMAP MS= 46.853515625
SET BG BITMAP MS= 46.772705078125
SET BG BITMAP MS= 46.79248046875
SET BG BITMAP MS= 46.845703125
SET BG BITMAP MS= 46.81884765625
SET BG BITMAP MS= 46.848388671875
SET BG BITMAP MS= 46.845458984375
SET BG BITMAP MS= 46.853271484375
SET BG BITMAP MS= 46.8486328125
SET BG BITMAP MS= 46.842529296875
SET BG BITMAP MS= 46.84521484375
SET BG BITMAP MS= 46.845458984375
SET BG BITMAP MS= 46.8017578125
SET BG BITMAP MS= 46.8505859375
SET BG BITMAP MS= 46.857666015625
SET BG BITMAP MS= 46.853515625
SET BG BITMAP MS= 46.847900390625
SET BG BITMAP MS= 62.470458984375
SET BG BITMAP MS= 46.868408203125
SET BG BITMAP MS= 46.84228515625
SET BG BITMAP MS= 46.847412109375
SET BG BITMAP MS= 46.8515625
SET BG BITMAP MS= 46.837158203125
SET BG BITMAP MS= 62.46875
SET BG BITMAP MS= 62.46923828125
SET BG BITMAP MS= 62.474853515625
SET BG BITMAP MS= 46.85302734375
SET BG BITMAP MS= 62.447021484375
SET BG BITMAP MS= 62.474365234375
SET BG BITMAP MS= 62.471923828125
SET BG BITMAP MS= 62.43212890625
SET BG BITMAP MS= 46.848876953125
SET BG BITMAP MS= 62.472412109375
SET BG BITMAP MS= 62.468505859375
SET BG BITMAP MS= 62.51220703125
SET BG BITMAP MS= 62.41455078125
SET BG BITMAP MS= 62.417236328125
SET BG BITMAP MS= 62.47021484375
SET BG BITMAP MS= 62.501953125
SET BG BITMAP MS= 62.4287109375
SET BG BITMAP MS= 46.843994140625
SET BG BITMAP MS= 62.46630859375
SET BG BITMAP MS= 62.476806640625
SET BG BITMAP MS= 62.467041015625
SET BG BITMAP MS= 69.049560546875
SET BG BITMAP MS= 69.44189453125
SET BG BITMAP MS= 67.87939453125
SET BG BITMAP MS= 60.30517578125
SET BG BITMAP MS= 46.8681640625

Я надеюсь, что кто-то может помочь мне воспроизвести эту проблему и помочь мне понять, почему тестируемый метод set_background_image_to_ss занимает больше времени. После небольшого количества итераций увеличение времени выполнения действительно нарушает мою программу. Спасибо.

Ответы [ 2 ]

0 голосов
/ 10 марта 2020

Все ли изображения одинакового размера?
Я переместил создание растрового изображения в init панели, оставив только SetBitmap и преобразование изображений в set_background_image_to_ss.
Тем временем я составил фиктивный список из 20 000 изображений примерно одинакового размера и не вижу никакого реального снижения скорости вообще.

import time
import glob
import wx

# APP
class MyApp(wx.App):

    def __init__(self):
        # 2 images roughly the same size
        self.images = glob.glob('./image3/*.png')
        # falsify 20000 images
        self.images = self.images * 10000
        self.loop_count = 0
        super().__init__(clearSigInt=True)

    def MainLoop(self):

        evtloop = wx.GUIEventLoop()
        #old = wx.EventLoop.GetActive()
        wx.EventLoop.SetActive(evtloop)

        for i in self.images:

            # this is the only instruction in the customized main loop that I added,
            # everything else is straight out of the example
            self.frame.panel.set_background_image_to_ss(i)

            while evtloop.Pending():
                evtloop.Dispatch()

            # i also changed the sleep from 0.1s in the example to 0.03.
            # either way the execution time increases over time.
            time.sleep(0.01)

            evtloop.ProcessIdle()

        #wx.EventLoop.SetActive(old)


    def OnInit(self):

        self.frame = MyFrame(self)
        self.frame.Show(True)

        self.SetTopWindow(self.frame)

        self.keepGoing = True
        return True

# FRAME
class MyFrame(wx.Frame):

    def __init__(self, app_obj, title="CM1", pos=(100, 100), size=(760,800)):

        super().__init__(None, title=title, pos=pos, size=wx.Size(size))

        self.init_panel(app_obj)

    def init_panel(self, app_obj):

        self.panel = MyPanel(self, app_obj)

# PANEL
class MyPanel(wx.Panel):

    def __init__(self, parent, app_obj):

        super().__init__(parent=parent)
        self.loop = app_obj.loop_count
        self.bmp1 = wx.Image(app_obj.images[0], wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        self.bitmap1 = wx.StaticBitmap(self, -1, self.bmp1, (0, 0))

    # PROBLEM METHOD
    def set_background_image_to_ss(self, path):
        self.bmp1 = wx.Image(path, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        curr_milliseconds_loop = time.time() * 1000
        self.bitmap1.SetBitmap(self.bmp1)
        self.loop += 1
        print("Loop:",self.loop,"SET BG BITMAP MS=", time.time() * 1000 - curr_milliseconds_loop)


app = MyApp()
app.MainLoop()

Скорость в начале:

Loop: 155 SET BG BITMAP MS= 1.70263671875
Loop: 156 SET BG BITMAP MS= 2.387939453125
Loop: 157 SET BG BITMAP MS= 2.416748046875
Loop: 158 SET BG BITMAP MS= 1.94580078125
Loop: 159 SET BG BITMAP MS= 1.8955078125
Loop: 160 SET BG BITMAP MS= 1.4580078125
Loop: 161 SET BG BITMAP MS= 2.04833984375
Loop: 162 SET BG BITMAP MS= 2.198486328125
Loop: 163 SET BG BITMAP MS= 1.79150390625
Loop: 164 SET BG BITMAP MS= 5.07958984375
Loop: 165 SET BG BITMAP MS= 1.69580078125

Скорость в конце:

Loop: 19925 SET BG BITMAP MS= 2.36962890625
Loop: 19926 SET BG BITMAP MS= 2.014892578125
Loop: 19927 SET BG BITMAP MS= 1.75390625
Loop: 19928 SET BG BITMAP MS= 1.5390625
Loop: 19929 SET BG BITMAP MS= 1.9013671875
Loop: 19930 SET BG BITMAP MS= 2.01953125
Loop: 19931 SET BG BITMAP MS= 1.921875
Loop: 19932 SET BG BITMAP MS= 1.669677734375
Loop: 19933 SET BG BITMAP MS= 1.630126953125
Loop: 19934 SET BG BITMAP MS= 2.14501953125
Loop: 19935 SET BG BITMAP MS= 2.1103515625
0 голосов
/ 09 марта 2020

Я думаю, что нашел решение.

Я никогда не устанавливал self.bg_img равным -1 после инициализации первого изображения, поэтому предложение else не выполнялось, а предыдущее изображение не уничтожалось перед добавлением новый. Изменение этого параметра, похоже, решило проблему.

Спасибо тем, кто это просмотрел.

...