is there a way to speed up this tablesort code?

L

loc2006

I got this tablesort code from
http://www.brainjar.com/dhtml/tablesort/default7.asp

This is very slow for my table of 10 columns and 400 rows. Is there a
way to optimize this code make it screaming fast?

function sortTable(id, col, rev) {

// Get the table or table section to sort.
var tblEl = document.getElementById(id);

// The first time this function is called for a given table, set up
an
// array of reverse sort flags.
if (tblEl.reverseSort == null) {
tblEl.reverseSort = new Array();
// Also, assume the team name column is initially sorted.
tblEl.lastColumn = 1;
}

// If this column has not been sorted before, set the initial sort
direction.
if (tblEl.reverseSort[col] == null)
tblEl.reverseSort[col] = rev;

// If this column was the last one sorted, reverse its sort
direction.
if (col == tblEl.lastColumn)
tblEl.reverseSort[col] = !tblEl.reverseSort[col];

// Remember this column as the last one sorted.
tblEl.lastColumn = col;

// Set the table display style to "none" - necessary for Netscape 6
// browsers.
var oldDsply = tblEl.style.display;
tblEl.style.display = "none";

// Sort the rows based on the content of the specified column using a
// selection sort.

var tmpEl;
var i, j;
var minVal, minIdx;
var testVal;
var cmp;

for (i = 0; i < tblEl.rows.length - 1; i++) {

// Assume the current row has the minimum value.
minIdx = i;
minVal = getTextValue(tblEl.rows.cells[col]);

// Search the rows that follow the current one for a smaller value.
for (j = i + 1; j < tblEl.rows.length; j++) {
testVal = getTextValue(tblEl.rows[j].cells[col]);
cmp = compareValues(minVal, testVal);
// Negate the comparison result if the reverse sort flag is set.
if (tblEl.reverseSort[col])
cmp = -cmp;
// Sort by the second column (team name) if those values are
equal.
if (cmp == 0 && col != 1)
cmp = compareValues(getTextValue(tblEl.rows[minIdx].cells[1]),
getTextValue(tblEl.rows[j].cells[1]));
// If this row has a smaller value than the current minimum,
remember its
// position and update the current minimum value.
if (cmp > 0) {
minIdx = j;
minVal = testVal;
}
}

// By now, we have the row with the smallest value. Remove it from
the
// table and insert it before the current row.
if (minIdx > i) {
tmpEl = tblEl.removeChild(tblEl.rows[minIdx]);
tblEl.insertBefore(tmpEl, tblEl.rows);
}
}

// Make it look pretty.
makePretty(tblEl, col);

// Set team rankings.
//setRanks(tblEl, col, rev);

// Restore the table's display style.
tblEl.style.display = oldDsply;

return false;
}

function makePretty(tblEl, col) {

var i, j;
var rowEl, cellEl;

// Set style classes on each row to alternate their appearance.
for (i = 0; i < tblEl.rows.length; i++) {
rowEl = tblEl.rows;
rowEl.className = rowEl.className.replace(rowTest, "");
if (i % 2 != 0)
rowEl.className += " " + rowClsNm;
rowEl.className = normalizeString(rowEl.className);
// Set style classes on each column (other than the name column) to
// highlight the one that was sorted.
for (j = 1; j < tblEl.rows.cells.length; j++) {
cellEl = rowEl.cells[j];
cellEl.className = cellEl.className.replace(colTest, "");
if (j == col)
cellEl.className += " " + colClsNm;
cellEl.className = normalizeString(cellEl.className);
}
}

// Find the table header and highlight the column that was sorted.
var el = tblEl.parentNode.tHead;
rowEl = el.rows[el.rows.length - 1];
// Set style classes for each column as above.
for (i = 1; i < rowEl.cells.length; i++) {
cellEl = rowEl.cells;
cellEl.className = cellEl.className.replace(colTest, "");
// Highlight the header of the sorted column.
if (i == col)
cellEl.className += " " + colClsNm;
cellEl.className = normalizeString(cellEl.className);
}
}
 
T

Thomas 'PointedEars' Lahn

I got this tablesort code from
http://www.brainjar.com/dhtml/tablesort/default7.asp

This is very slow for my table of 10 columns and 400 rows. Is there a
way to optimize this code make it screaming fast?

function sortTable(id, col, rev) {
// Get the table or table section to sort.
var tblEl = document.getElementById(id);

// The first time this function is called for a given table, set up
// an array of reverse sort flags.
if (tblEl.reverseSort == null) {
tblEl.reverseSort = new Array();
// Also, assume the team name column is initially sorted.
tblEl.lastColumn = 1;
}

It is error-prone to add new properties to host objects like
HTMLTableElement objects.
// Sort the rows based on the content of the specified column using a
// selection sort.

Selection sort is probably the most intuitive sort algorithmbut not a very
efficient one; it has a time complexity of O(n^2) in the best case, average
case and worst case. Try something faster like Quicksort; it has a time
complexity of O(n*log(n)) in the best case and the average case, and O(n^2)
only in the worst case.

<URL:http://en.wikipedia.org/wiki/Sorting_algorithm>

Maybe it is even faster to store the rows into an array, sort that
array by criteria using Array.prototype.sort(), and reorder the actual
HTMLTableRowElement objects in the comparator or rebuild the table
afterwards according to the array.
[...]
for (i = 0; i < tblEl.rows.length - 1; i++) {

Replace with

for (var i = 0, len = tblEl.rows.length - 1; i < len; i--)
{
[...]
for (j = i + 1; j < tblEl.rows.length; j++) {

Replace with

for (var j = i + 1, len2 = tblEl.rows.length; j < len; j++)
{

But you should instead use the `tbody' element to distinguish between table
rows in the table header and the table body. HTMLTableSectionElement
objects have a `rows' property, too.

// By now, we have the row with the smallest value. Remove it from
the
// table and insert it before the current row.
if (minIdx > i) {
tmpEl = tblEl.removeChild(tblEl.rows[minIdx]);
tblEl.insertBefore(tmpEl, tblEl.rows);
}
}


You do not need to remove the element from the DOM tree yourself before
you insert it again. If the first parameter of Node::insertBefore
refers to a node that is already in the DOM tree, it is first removed:

[...]
function makePretty(tblEl, col) {
[...]
if (i % 2 != 0)

Use (i & 1) to test for an odd number i instead, it is probably faster.
rowEl.className += " " + rowClsNm;
rowEl.className = normalizeString(rowEl.className);
// Set style classes on each column (other than the name column) to
// highlight the one that was sorted.
for (j = 1; j < tblEl.rows.cells.length; j++) {


See above.
[...]
// Set style classes for each column as above.
for (i = 1; i < rowEl.cells.length; i++) {

See above.

And probably I forgot to mention something.


HTH

PointedEars
 
T

Thomas 'PointedEars' Lahn

I got this tablesort code from
http://www.brainjar.com/dhtml/tablesort/default7.asp

This is very slow for my table of 10 columns and 400 rows. Is there a
way to optimize this code make it screaming fast?

function sortTable(id, col, rev) {
// Get the table or table section to sort.
var tblEl = document.getElementById(id);

// The first time this function is called for a given table, set up
// an array of reverse sort flags.
if (tblEl.reverseSort == null) {
tblEl.reverseSort = new Array();
// Also, assume the team name column is initially sorted.
tblEl.lastColumn = 1;
}

It is error-prone to add new properties to host objects like
HTMLTableElement objects.
// Sort the rows based on the content of the specified column using a
// selection sort.

Selection sort is probably the most intuitive sorting algorithm, but not a
very efficient one; it has a time complexity of O(n^2) in the best case,
average case and worst case. Try something faster like Quicksort; it has a
time complexity of O(n*log(n)) in the best case and the average case, and
O(n^2) only in the worst case.

<URL:http://en.wikipedia.org/wiki/Sorting_algorithm>

Maybe it is even faster to store the rows into an array, sort that
array by criteria using Array.prototype.sort(), and reorder the actual
HTMLTableRowElement objects in the comparator or rebuild the table
afterwards according to the array.
[...]
for (i = 0; i < tblEl.rows.length - 1; i++) {

Replace with

for (var i = 0, len = tblEl.rows.length - 1; i < len; i--)
{
[...]
for (j = i + 1; j < tblEl.rows.length; j++) {

Replace with

for (var j = i + 1, len2 = tblEl.rows.length; j < len; j++)
{

But you should instead use the `tbody' element to distinguish between table
rows in the table header and the table body. HTMLTableSectionElement
objects have a `rows' property, too.

// By now, we have the row with the smallest value. Remove it from
the
// table and insert it before the current row.
if (minIdx > i) {
tmpEl = tblEl.removeChild(tblEl.rows[minIdx]);
tblEl.insertBefore(tmpEl, tblEl.rows);
}
}


You do not need to remove the element from the DOM tree yourself before
you insert it again. If the first parameter of Node::insertBefore
refers to a node that is already in the DOM tree, it is first removed:

[...]
function makePretty(tblEl, col) {
[...]
if (i % 2 != 0)

Use (i & 1) to test for an odd number i instead, it is probably faster.
rowEl.className += " " + rowClsNm;
rowEl.className = normalizeString(rowEl.className);
// Set style classes on each column (other than the name column) to
// highlight the one that was sorted.
for (j = 1; j < tblEl.rows.cells.length; j++) {


See above.
[...]
// Set style classes for each column as above.
for (i = 1; i < rowEl.cells.length; i++) {

See above.

And probably I forgot to mention something.


HTH

PointedEars
 
B

bwucke

(e-mail address removed) napisal(a):
I got this tablesort code from
http://www.brainjar.com/dhtml/tablesort/default7.asp

This is very slow for my table of 10 columns and 400 rows. Is there a
way to optimize this code make it screaming fast?

Move it to server side, do the sorting in the database app, send out
ready HTML.
Seriously, you can speed up the sorting algorithm as much as you want,
but juggling 400 elements using DOM functions WILL be slow no matter
what.
I bet using CSS, relative positioning and just changing Y-positions of
existing table rows would be much faster, but I'm scared of my own idea.
 
J

Jonas Raoni

(e-mail address removed) escreveu:
(e-mail address removed) napisal(a):

Move it to server side, do the sorting in the database app, send out
ready HTML.

For paged data, sorting by JS will have a really strange result... But
if you don't have a huge amount of records, I think you should use it,
it's better than waiting for a server answer :)

Give a try to my friend's code, it's working reasonably fast...

You can see the code [http://jsfromhell.com/js/TableSort.js] working in
the lists [http://jsfromhell.com/dhtml], the useful part for you is the
"sortCol" function =]

This is just the sorting initialization:
[http://jsfromhell.com/js/sortCode.js]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top