Mam problemy z wydajnością podczas wstawiania wielu wierszy do widoku drzewa GTK (przy użyciu PyGTK) - lub podczas modyfikowania wielu wierszy. Problem polega na tym, że model wydaje się uciekać po każdej zmianie (wstawienie/modyfikacja). To powoduje, że GUI zawiesza się na kilka sekund. Pozostawienie modelu nieposortowanego przez wykomentowanie model.set_sort_column_id(SOME_ROW_INDEX, gtk.SORT_ASCENDING)
eliminuje te problemy.GtkTreeView wstawianie/aktualizowanie kary wydajności z powodu sortowania
Dlatego chciałbym wyłączyć sortowanie podczas wstawiania lub modyfikowania modelu, a następnie włączyć je później. Niestety, sortowanie nie może być wyłączone z model.set_sort_column_id(-1, gtk.SORT_ASCENDING)
. Korzystanie z funkcji zamrażania/rozmrażania nie działa albo:
treeview.freeze_child_notify()
try:
for row in model:
# ... change something in row ...
finally:
treeview.thaw_child_notify()
Tak, jak mogę wyłączyć sortowanie? Czy istnieje lepsza metoda wprowadzania/modyfikacji luzem?
Rozwiązanie
Dzięki informacjom i linki bobince przewidziane w swojej odpowiedzi, sprawdziłem niektóre z alternatyw:
1) Dummy sortowania
tv.freeze_child_notify()
sortSettings = model.get_sort_column_id()
model.set_default_sort_func(lambda *unused: 0) # <-- can also use None but that is slower!
# model.set_default_sort_func(lambda *unused: 1) <-- slow
# model.set_default_sort_func(lambda *unused: -1) <-- crash (access violation in gtk_tree_store_move_after?!)
model.set_sort_column_id(-1, gtk.SORT_ASCENDING)
# change rows
model.set_sort_column_id(*sortSettings)
tv.thaw_child_notify()
Spowodowało to spadek czasu z około 11 sekund do 2 sekund. Łał! Ale może być lepiej, to było tylko na 1000 wierszy.
2) usuwanie modelu podczas aktualizacji
tv.set_model(None)
# change rows
tv.set_model(model)
Brak zauważalnej różnicy, 11 sekund.
3) manekin sortowania chłodnej i generator trick w PyGTK FAQ
def gen():
tv.freeze_child_notify()
sortSettings = model.get_sort_column_id()
model.set_default_sort_func(lambda *unused: 0)
model.set_sort_column_id(-1, gtk.SORT_ASCENDING)
i = 0
for row in rowsToChange:
i += 1
# change something
if i % 200 == 0:
# freeze/thaw not really necessary here as sorting is wrong because of the
# default sort function
yield True
model.set_sort_column_id(*sortSettings)
tv.thaw_child_notify()
yield False
g = gen()
if g.next(): # run once now, remaining iterations when idle
gobject.idle_add(g.next)
Wynik: same oszacowane 2 sekund, w roztworze 1), ale GUI reaguje w tym czasie. Wolę tę metodę. Modulo 200 można zmodyfikować, aby interfejs GUI był bardziej lub mniej reaktywny, jeśli zajdzie taka potrzeba.
Może nawet podklasę gtk.TreeStore
można uzyskać, aby uzyskać lepsze wyniki? Jeszcze tego nie próbowałem, ale opcja 3) jest na razie wystarczająco dobra.
Dzięki, to było naprawdę pomocne :) Zobacz moje pytanie dotyczące niektórych rozwiązań, które przetestowałem na podstawie podanych informacji. – AndiDog