Leistungseinschränkungen des Tkinter-Canvas

8

Ich habe eine einfache Anwendung erstellt, um ein Streudiagramm von Daten mit dem Canvas-Widget von Tkinter anzuzeigen (siehe einfaches Beispiel unten). Nach dem Plotten von 10.000 Datenpunkten wird die Anwendung sehr verzögert, was durch das Ändern der Fenstergröße erkannt werden kann.

Ich stelle fest, dass jedes Element, das dem Canvas hinzugefügt wird, ein Objekt ist, so dass es zu irgendeinem Zeitpunkt einige Leistungsprobleme geben kann. Ich habe jedoch erwartet, dass dieses Level viel höher ist als 10.000 einfache ovale Objekte. Außerdem könnte ich einige Verzögerungen akzeptieren, wenn ich die Punkte zeichne oder mit ihnen interagiere, aber nachdem sie gezeichnet wurden, warum sollte das Fenster nur so langsam skaliert werden?

Nach dem Lesen von Leistungsproblemen von effbot mit dem Canvas-Widget scheint es, dass während der Größenanpassung einige unnötige fortlaufende Leerlauf-Tasks benötigt werden ignoriert werden:

  

Das Canvas-Widget implementiert eine direkte Schadens / Reparatur-Anzeige   Modell. Änderungen an der Zeichenfläche und externen Ereignissen wie Expose sind   alles als "Schaden" auf dem Bildschirm behandelt. Das Widget behält eine schmutzige   Rechteck, um den beschädigten Bereich zu verfolgen.

     

Wenn das erste Schadensereignis eintritt, registriert die Zeichenfläche eine Leerlaufaufgabe   (mit after_idle), mit dem der Canvas "repariert" wird, wenn der   Das Programm kehrt zur Hauptschleife von Tkinter zurück. Sie können Updates durch erzwingen   Aufruf der update_idletasks-Methode.

Die Frage ist also, ob es eine Möglichkeit gibt, update_idletasks zu verwenden, um die Anwendung reaktionsfähiger zu machen, wenn die Daten einmal geplottet wurden? Wenn ja, wie?

Unten ist das einfachste Arbeitsbeispiel. Versuchen Sie, die Größe des Fensters nach dem Laden zu ändern, um zu sehen, wie verzögert die Anwendung wird.

Aktualisieren

Ich habe dieses Problem ursprünglich in Mac OS X (Mavericks) beobachtet, wo ich eine wesentliche Erhöhung der CPU-Auslastung erhalte, wenn ich nur die Größe des Fensters ändere. Auf Ramchandras Kommentare hin habe ich das in Ubuntu getestet und das scheint nicht zu passieren. Vielleicht ist dies ein Mac Python / Tk-Problem? Wäre nicht der erste, auf den ich gestoßen bin, sehe meine andere Frage:

PNG-Anzeige in PIL gebrochen auf OS X Mavericks?

Könnte jemand auch in Windows versuchen (ich habe keinen Zugriff auf eine Windows-Box)?

Ich kann versuchen, auf dem Mac mit meiner eigenen kompilierten Version von Python zu laufen und zu sehen, ob das Problem weiterhin besteht.

Minimales Arbeitsbeispiel:

%Vor%     
Fiver 09.11.2013, 23:09
quelle

2 Antworten

3

Es gibt tatsächlich ein Problem mit einigen Distributionen von TKinter und OS Mavericks. Anscheinend müssen Sie ActiveTcl 8.5.15.1 installieren. Es gibt einen Fehler bei TKinter und OS Mavericks. Wenn es immer noch nicht schnell genug ist, gibt es unten noch ein paar Tricks.

Sie könnten die mehreren Punkte immer noch in einem Bild speichern. Wenn Sie es nicht oft ändern, sollte es immer noch schneller sein. Wenn Sie sie häufiger ändern, gibt es andere Möglichkeiten, ein Python-Programm zu beschleunigen. Dieser andere Stack-Überlauf-Thread behandelt die Verwendung von Cython, um eine schnellere Klasse zu erstellen. Da der Großteil der Verlangsamung wahrscheinlich auf die Grafik zurückzuführen ist, wird dies wahrscheinlich nicht viel schneller, aber es könnte helfen.

Vorschläge zur Beschleunigung einer Entfernungsberechnung

Sie könnten auch die for-Schleife beschleunigen, indem Sie vorher einen Iterator (ex: iterator = (s.upper () für s in list_to_iterate_through)) definieren, aber dies wird aufgerufen, um das Fenster zu zeichnen, nicht ständig, da das Fenster beibehalten wird Das sollte also nicht viel ausmachen. Eine weitere Möglichkeit, Dinge zu beschleunigen, die aus Python-Dokumenten stammen, besteht darin, die Häufigkeit von Pythons Hintergrundüberprüfungen zu verringern:

"Der Python-Interpreter führt einige periodische Überprüfungen durch. Insbesondere entscheidet er, ob ein anderer Thread ausgeführt werden soll oder nicht und ob ein ausstehender Aufruf ausgeführt wird (normalerweise ein Aufruf durch einen Signal-Handler). Die meiste Zeit ist da Da die Ausführung dieser Prüfungen bei jedem Durchlauf der Interpreterschleife die Vorgänge verlangsamen kann, gibt es eine Funktion im sys-Modul setcheckinterval, die Sie aufrufen können, um dem Interpreter mitzuteilen, wie oft diese regelmäßigen Prüfungen durchgeführt werden von Python 2.3 ist es auf 10 voreingestellt. In 2.3 wurde das auf 100 erhöht. Wenn Sie nicht mit Threads arbeiten und nicht erwarten, dass viele Signale abgefangen werden, kann die Performance des Interpreters durch das Setzen auf einen größeren Wert erheblich verbessert werden . "

Eine weitere Sache, die ich online gefunden habe, ist, dass die Einstellung der Zeit durch Ändern von os.environ ['TZ'] das Programm etwas beschleunigen wird.

Wenn das immer noch nicht funktioniert, ist es wahrscheinlich, dass TKinter nicht das beste Programm ist, um dies zu tun. Pygame könnte schneller sein, oder ein Programm, das die Grafikkarte wie Open GL verwendet (ich glaube nicht ist jedoch für Python verfügbar)

    
someone-or-other 19.11.2013 04:14
quelle
0

Tk muss stecken bleiben und über all diese Ovale schleifen. Ich bin nicht sicher, dass die Leinwand jemals dazu gedacht war, so viele Gegenstände gleichzeitig zu halten.

Eine Lösung besteht darin, Ihre Zeichnung in ein Bildobjekt zu zeichnen und dann das Bild zu platzieren in deine Leinwand.

    
Oblivion 16.11.2013 05:32
quelle