TableRowSorter... zu langsam

Status
Nicht offen für weitere Antworten.

roxX0r

Mitglied
Ich hab da nochmal ein Prob mit dem TableRowSorter.

Mein Programm liest etwas in einem Seperaten Thread aus, berechnet dort auch etwas und schickt dann an die Tabelle einen Vector, der dort einfach hinzugefügt wird. In meinem extra Thread läuft das so:

Java:
             //Thread arbeitet ....

                EventQueue.invokeLater(new Runnable() {

                    public void run() {

                        //otm ist ein String Vector 
                        model.addaRow(otm);
                        }

                    }
                });

Im Thread gibts ne Schleife, die ca. 1000 mal durchläuft und auch soviele neuen Zeilen in die Tabelle der GUI schreibt. Das funktioniert auch alles sehr schön, nur gibts jetzt ein Problem mit dem RowSorter. Die Tabelle wird rasch sehr groß und ab einer bestimmten größe fängt die GUI an zu haken und nicht mehr zu reagieren, die Informationen des Arbeiter-Threads kommen schneller als der RowSorter die Tabelle sortieren kann (vermute ich). Ist kein RowSorter auf der Tabelle, ist die GUI ganz geschmeidig ... reagiert sofort wenn man auf eine Zeile klickt, oder scrollt. Sobald der rowSorter aktiv ist, hakt es irgendwann.

Jemand eine Idee, wie ich das irgendwie besser hinbekomme ?

Noch kurz zur Implementation der Methode addaRow(): dort wird nur der dataVector der Tabelle um einen Eintrag erweitert und danach wird der TabelRowSorter neu gesetzt. Der muss nach jeder Änderung des DataVectors neu gesetzt werden ...
 
Ja aber während der andere Thread die ganze Zeit neue Rows dranhängt, soll der Benutzer schon die sortierte Tabelle sehen und damit arbeiten. Neue Datensätze sollen dann direkt einsortiert reingeschrieben werden. Funzt alles perfekt, nur die Performance macht irgendwann dicht ... getColumnClass liefert auch direkt Double zurück damit der RowSorter nicht erst konvertieren muss.
Wenn ich das sortieren jetzt selbst implemetiere und dann den dataVector jedesmal mit Collection.sort sortiere... ob das performance bringt?
 
Hm. Ein eigenes TableModel schreiben KÖNNTE schneller sein, aber sicher nicht, wenn du jedes mal Collections.sort machst. Sowas macht der TableSorter ja mit ziemlicher Sicherheit auch: Wenn man 100 Elemente einfügt, dann sortiert er erst 1, dann 2,3,4... dann 99... und nur weil dann noch eins dazukommt, macht er die komplette Sortierung der 99 anderen Elemente nochmal neu - das ist reinste Zeitverschwendung...

Stattdessen könntest du, wenn du sowieso ein eigenes TableModel schreibst, dort eine Methode "addRowSorted" einführen, die einfach durch die intern für die Tabellenzeilen vorliegende Liste läuft, und die neue Zeile an der passenden Stelle einfügt. Damit wird die Tabelle mit jedem einfügen ständig sortiert gehalten. Das wäre sogar einer der wenigen Fälle, wo sich eine LinkedList anbieten würde...
 
Huh? Wieso ist da LinkedList besser? Auf einer ArrayList kann man ja z. B. binäre Suche verwenden. Einfacher klingt aber ein SortedSet.
 
Beim SortedSet ist's mit der Implementierung des indizierten Zugiffs für's TableModel interface ein bißchen schwierig (also, es geht, natürlich... 😉 ). Und ... das Einfügen an einer beliebigen Position ist bei LinkedList schneller. Bei einer ArrayList müssen ja alle dahinter liegenden Elemente um 1 weitergeschoben werden.
 
Ok, für indizierten Zugriff ist das Set natürlich nix, das stimmt. Es ging ja hier um ein eigenes Model...
Und bei den Listen... daran habe ich gerade auch nicht gedacht (Abstraktion ist toll). Bei den beiden ist halt der Tradeoff zwischen Zugriff und Speicherung verschieden. Ich würde aber zumindest mal beide Varianten durchprobieren. Dürfte ja keinen großen Aufwand machen.
 
Noch ein anderer Tipp: Je nachdem, um wie viele Zeilen es da geht, könnte es sinnvoll sein, die Zeilen zu sammeln. Also, JEDE Zeile einzeln auf dem EDT in die Tabelle zu legen ist vielleicht gar nicht nötig. Wenn man also z.B. 10000 Zeilen einfügen wollte, wäre es ggf. sinnvoller, nicht 10000x1 Zeile einzufügen, sondern nur 1000x10 Zeilen.
Die Klasse "SwingWorker" bietet schon ansatzweise Mechanismen dafür: Die ruft bei längeren Berechnungen zwischendurch eine Methode (ich glaube "publish") auf, die eine Liste von "Chunks", also kleinen Zwischenergebnissen, liefert (bei dir wären das die Zeilen). Das sortierte Einfügen kann man damit auch recht schnell machen, und es könnte insgesamt noch schneller sein... Musst du aber selbst überlegen/ausprobieren.
 
Danke für die Tipps.

Ich machs jetzt so, dass ich nur alle 30 Teilen die Tabelle neusortiere. Das bringt eigentlich schon sehr viel. Wäre sicher noch möglich, das noch besser hinzubekommen, aber so reichts 🙂
Danke nochmal
 
Eigentlich war das letzte als eine zusätzliche Möglichkeit gemeint - so kommt er (selbst bei 30er-Blöcken) aus dem Sortieren ja nicht mehr raus... aber ... OK.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben