Improving TableRowSorter Filter Performance

Hi, I currently have a TableModel with over 17300 rows of data, which has a TableRowSorter attached to provide sorting and filtering on the JTable. Everything works fine except that filtering the table takes to long, even on a Wndow Vista machine with an Intel Core 2 Duo (3.6ghz processor)

Is there any known way to improve the filtering performance on TableRowSorter? It should be noted however, that Sorting with the same data does not take as long (at times). It is also much slower when all the necessary bells and whistles or rendering are included.

Here is an example piece of code:

import java.awt.*;

import java.awt.event.*;

import java.util.*;

import javax.swing.*;

import javax.swing.event.*;

import javax.swing.table.*;

publicclass Trialextends JFrame{

public JTable table;

public DefaultTableModel model;

public TableRowSorter sorter;

public JTextField filterField;

public Trial(){

super("Filter Test");

setDefaultCloseOperation(EXIT_ON_CLOSE);

Vector<String> cols =new Vector<String>();

cols.addElement("Column 1");

cols.addElement("Column 2");

cols.addElement("Column 3");

cols.addElement("Column 4");

cols.addElement("Column 5");

cols.addElement("Column 6");

Vector<Vector><Object>> rows =new Vector<Vector><Object>>();

for(int i = 0; i < 20000; i++){

Vector<Object> row =new Vector<Object>();

row.addElement("Column 1 Data " + (i+1) );

row.addElement("Some Data " + (i+1) );

row.addElement("Column 3 Data " + (i+1) );

row.addElement("Even More Data " + (i+1) );

row.addElement("Column 5 Data " + (i+1) );

row.addElement("Please No More Data " + (i+1) );

rows.addElement( row );

}

model =new DefaultTableModel(rows, cols);

table =new JTable( model );

table.setRowSorter(new TableRowSorter(model) );

JScrollPane scr =new JScrollPane(table);

filterField =new JTextField(20);

filterField.addCaretListener(new CaretListener(){

publicvoid caretUpdate(CaretEvent e){

if(table.getRowSorter() ==null)return;

setCursor( Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR) );

String text = filterField.getText();

((DefaultRowSorter)table.getRowSorter()).setRowFilter(RowFilter.regexFilter(".*" + text +".*"));

setCursor( Cursor.getDefaultCursor() );

}

});

JPanel filterPanel =new JPanel(new FlowLayout(FlowLayout.LEFT) );

filterPanel.add(new JLabel("Filter: ") );

filterPanel.add( filterField );

getContentPane().add( filterPanel, BorderLayout.NORTH );

getContentPane().add( scr, BorderLayout.CENTER);

pack();

setLocationRelativeTo(null);

try{

setExtendedState(MAXIMIZED_BOTH);

}catch(Exception e){}

setVisible(true);

}

publicstaticvoid main(String[] args){

new Trial();

}

}

Any ideas as to how performance (or percieved performance) can be improved would gladly be apprieciated.

ICE

[5346 byte] By [icewalker2ga] at [2007-11-27 11:08:46]
# 1

hi

just one idea,

override TableRowSorter

and then

@Override

public void sort()

{

}

there you write own sorting algorithm which is faster, and call the fireTableDataChanged()

may be that will be faster.. just an idea...

like this

table.setRowSorter( new myTableRowSorter(model) );

//...............................

//............................

class myTableRowSorter extends TableRowSorter

{

public myTableRowSorter()

{

super();

}

public myTableRowSorter(TableModel model)

{

super(model);

}

@Override

public Comparator getComparator(int column)

{

System.out.println("myTableRowSorter.getComparator()");

Comparator comp = super.getComparator(column);

return comp;

}

@Override

public void sort()

{

//your own sorting algorithm

model.fireTableDataChanged();

}

}

regards

Aniruddha

Aniruddha-Herea at 2007-7-29 13:31:01 > top of Java-index,Desktop,Core GUI APIs...
# 2

The overhead of compiling the regex pattern 17300 times is killing you. You can significant improve the performance by overriding the regexFilter (in RowFilter) by compiling it once and using the compiled pattern 17299 times.

;o)

V.V.

PS: Just wondering out loud why the power-to-be did not have the foresight to provide a method that accept a pre-compiled regex ;o(

Message was edited by:

viravan

viravana at 2007-7-29 13:31:01 > top of Java-index,Desktop,Core GUI APIs...
# 3

> The overhead of compiling the regex pattern 17300

> times is killing you.

Could you elaborate on this? From what I see, it appears to only compile

the pattern once, when this line is executed:((DefaultRowSorter)table.getRowSorter()).setRowFilter(RowFilter.regexFilter(".*" + text + ".*"));

Admittedly, all I did to check this was set a breakpoint in Pattern.compile, so

if it's using another method to compile it, that would be why I don't see it.

What I would have suggested is somehow overriding initializeFilteredMapping

(which you can't do because it's private, so you'd have to restructure the

whole thing) to somehow take into account the current filtered rows rather

than redoing the whole thing each time.

JayDSa at 2007-7-29 13:31:01 > top of Java-index,Desktop,Core GUI APIs...
# 4

> The overhead of compiling the regex pattern 17300

> times is killing you.

Is there anyway to precompile this somehow, assuming that is the problem, or maybe a suggestion as to a different pattern that can be used to return rows containing the supplied text. Looking the Pattern class myself now, so if anyone finds anything pls inform.

> so you'd have to restructure the whole thing to somehow take into account the current filtered rows rather than redoing the whole thing each time.

Not sure what you mean by this, could you elaborate?

> hi just one idea,

> override TableRowSorter

I tried that sometime earlier when I was creating a row grouping feature (Windows Vista or XP Explorer for example). Found out that is not an easy thing, and I'm glad someone (Swing Team) managed to come up with it. Save me the time, although it is not perfect.

ICE

icewalker2ga at 2007-7-29 13:31:01 > top of Java-index,Desktop,Core GUI APIs...
# 5

>Could you elaborate on this?

hmmm.., guess I should look a bit closer...

RowFilter.java contains a method named regexFilter (which compiles the expression) as well as a class named regexFilter (which does the matching).

Sorry about that! I don't have any answer for the sluggishness.

;o(

V.V.

viravana at 2007-7-29 13:31:01 > top of Java-index,Desktop,Core GUI APIs...
# 6

> > so you'd have to restructure the whole thing to

> somehow take into account the current filtered rows

> rather than redoing the whole thing each time.

>

> Not sure what you mean by this, could you elaborate?

Every time you change the filter, every row is checked against the filter.

If the filter is completely different, there is no avoiding this. If, however,

the filter is now just a more specific version of the previous (e.g.., the

filter was previously 99 and now you type an additional 9 to make it 999),

then you need only filter against the previously matched rows, some 560

rather than all 17300.

I expect this would speed things up.

On the other hand, the only way I see to do this is to completely reimplement

DefaultRowSorter and TableRowSorter, as you need access to the private

data of the former, and the latter extends the former.

JayDSa at 2007-7-29 13:31:01 > top of Java-index,Desktop,Core GUI APIs...
# 7

> On the other hand, the only way I see to do this is to completely reimplement DefaultRowSorter and TableRowSorter, as you need access to the private data of the former, and the latter extends the former

I actually tried to re-implement TableRowSorter initially but I when I went into the code, I realised I was poorly equiped to follow the index tricks that the Swing Team had put into that code. So I've sorta given up on it. Rather reduced the data in the database but even that didn't improve performance too much.

I'm now thinking along the lines of threading within the caretUpdate call. Not worked out the modalities but I'll get around to it. Right now, I've moved to other sections of functionality and will come back to this as and when possible

But any and all ideas are still welcome in the mean time

ICE

icewalker2ga at 2007-7-29 13:31:01 > top of Java-index,Desktop,Core GUI APIs...