テーブルのソートって何が一番良いんだろう
opera:cache のキャッシュ一覧で、tr 要素が1万あるテーブルをソートしようと思ってるんだけど、直感的にやりすぎて遅かった。
originalTable という変数にこんな感じの DocumentFragment を入れて、
opr000E8 | 2859 | http://hoge.com/hoge.jpg |
opr000EH | 56 | http://fuga.com/fuga.js |
opr000CS | 4698145 | http://piyo.com/piyo.flv |
こんなふうに並べ変えた DocumentFragment を作ると。
opr000EH | 56 | http://fuga.com/fuga.js |
opr000E8 | 2859 | http://hoge.com/hoge.jpg |
opr000CS | 4698145 | http://piyo.com/piyo.flv |
以下は opera:cache でブックマークレットとして実行できる。
javascript: (function() { var tbody = document.getElementsByTagName('tbody')[0]; function copyOriginalTable() { var df = document.createDocumentFragment(); var range = document.createRange(); range.selectNodeContents(tbody); range.setStartAfter(range.startContainer.firstChild); df = range.cloneContents(); return df; } var originalTable = copyOriginalTable(); function bucketSort(type) { var tr = originalTable.firstChild; if (type == 'size-ascendent') { var buckets = []; var b; var key; for (; tr; tr = tr.nextSibling) { key = tr.firstChild.nextSibling.innerText - 0; b = buckets[key]; if (b == undefined) { buckets[key] = [tr.cloneNode(true)]; } else { buckets[key][b.length] = tr.cloneNode(true); } } var df = document.createDocumentFragment(); for (var i = 0, n = buckets.length; i < n; i++) { if (buckets[i] == undefined) continue; for (var j = 0; j < buckets[i].length; j++) { df.appendChild(buckets[i][j]); } } return df; } var t0 = new Date().getTime(); var sizeAscendentTable = bucketSort('size-ascendent'); var t1 = new Date().getTime(); alert(t1 - t0); })();
自分のところでは実行時間4秒。使えねー。
ループ中でどの命令がボトルネックになっているかというのを簡単に調べる方法知ってる人は教えてください。
DocumentFragment までやらずに配列までで止めておくという方法もあるが、その場合はバケットソートじゃなくて何か別の方法でやる必要があるかも。
元データが DocumentFragment なのがいけないのかな。テーブルをそのまま切り取ったんだから一番手っ取り早いんだけど。一旦文字リテラルの配列にしてからソートして、そのインデックスだけ受け渡すということもできる。関数呼び出しはの回数あまり変わらんような決もするけど。DOM オブジェクトを扱わないでよくなる。
テーブルのソートの実例というのも見つけた。ソースは読んでない。
こんなのもあった。