javacodenameone

Table sort performance


I have a Codename One application that display form(s) with table(s) and sorts using table.sort(). The performance is poor if the table is large. In my case, if the table contains 1000+ rows it may take ten seconds to display / re-sort the table. I've altered my code to sort my data prior to creating the table and to not sort using table.sort(), but the problem remains when the user re-sorts the table, by selecting a column header - this occurs via table.sort().

I asked an AI agent for a summary of the table.sort() code and it replied:

Every sort rebuilds the entire model: You're replacing the model each time with a new SortableTableModel. setModel probably triggers a full redraw of the UI and creates a new internal structure (copying all rows, sorting them, etc.). ➔ Very expensive when your table is large.

Is there an alternative? If not, can table.sort() code be improved?

My code:

table.setSortSupported(true);
if (0 <= sortColumn) {
    table.sort(sortColumn, sortAscending);
}

Solution

  • In terms of performance for codename tables, manual sorting while avoiding table.sort() is the best option.

    table.sort() is slow because it wraps the model in a SortableTableModel, deep-copies data, rebuilds the entire UI with new components, triggers full layout/revalidation, and fails to reuse cells efficiently.

    With manual sorting, you sort only the raw data (not the UI), avoid deep copies, rebuild the table just once, and replace it bypassing the expensive model wrapping and UI reconstruction that table.sort() does.

    Default sorting snippet:

    Collections.sort(data, (row1, row2) -> {
        Object o1 = row1[column];
        Object o2 = row2[column];
    
        if (o1 instanceof Comparable && o2 instanceof Comparable) {
            return ascending ?
                    ((Comparable)o1).compareTo(o2) :
                    ((Comparable)o2).compareTo(o1);
        }
        return 0;
    });
    

    That is a "default" custom logic that will work with your items( you may override the compareTo method if needed) . Again, in terms of perfomarnce, this is much faster.


    After you manually sorted, create a new table:

    Table newTable = createTable(data, columnNames);
    newTable.setSortSupported(false); //do not sort
    

    Finally, change the old table for the new one:

    Container parent = table.getParent();
    int index = parent.getComponentIndex(table);
    
    parent.replaceAndWait(table, newTable, CommonTransitions.createFade(300));
    table = newTable;
    

    This is the best option I can guess to improve performance. You could benchmark it and check if it's faster than table.sort(), which absolutely will be.