ProcessSmartTabsの最適化
概要
タブ文字をホワイトスペースに置換する関数を最適化する。
別にそんなにボトルネックになっている箇所ではないが、見るからに非効率そうだったので私でも多少は改善できそうだ。
ということでトライしてみた。
Before
dp.sh.Highlighter.prototype.ProcessSmartTabs = function(code) { var lines = code.split('\n'); var result = ''; var tabSize = 4; var tab = '\t'; function InsertSpaces(line, pos, count) { var left = line.substr(0, pos); var right = line.substr(pos + 1, line.length); var spaces = ''; for(var i = 0; i < count; i++) spaces += ' '; return left + spaces + right; } function ProcessLine(line, tabSize) { if(line.indexOf(tab) == -1) return line; var pos = 0; while((pos = line.indexOf(tab)) != -1) { var spaces = tabSize - pos % tabSize; line = InsertSpaces(line, pos, spaces); } return line; } for(var i = 0; i < lines.length; i++) result += ProcessLine(lines[i], tabSize) + '\n'; return result; }
After
dp.sh.Highlighter.prototype.ProcessSmartTabs = function(code) { var lines = code.split('\n'); var tabSize = 4; var sptab = [""," "," "," "," "]; var t = '\t'; function ProcessLine(line, tabSize) { var pos = 0; while((pos = line.indexOf(t,pos)) != -1) line = line.substr(0, pos)+sptab[tabSize - pos % tabSize]+line.substr(pos + 1); return line; } for(var i = 0; i < lines.length; i++) lines[i] = ProcessLine(lines[i], tabSize); return lines.join("\n")+"\n"; }
感想
例によってWitchGarden側に詳細は記載している。
http://tsuge.astgate.biz/witchgarden/?dp%2esyntaxhighlighter%2f%ba%c7%c5%ac%b2%bd%c8%c7%a4%ce%ba%ee%c0%ae
resultをlines.joinに変えるだけで結構速くなるはず。
基本的にスクリプト型の言語はネイティブコードを呼ぶようにした方が速いので(当然だが)、劇的な速度アップが望めるのはjoinくらい。他は処理速度を上げるより、ソースコード量減量程度がメインだろう。一応少しは上げたつもりだが。
ものっそい気にいらないのはココ。
while((pos = line.indexOf(t,pos)) != -1) line = line.substr(0, pos)+sptab[tabSize - pos % tabSize]+line.substr(pos + 1);
場合によっては結構膨大なバッファを持つStringを三つ生成。しかも一行につきtab文字数分生成と破壊を繰り返す。うーむ・・。
行頭だけは別処理に分ければ最適化されるか、なんて思ったりもしたが、Web公開型ソースでそんなにタブらないだろうと思って結局やめておいた。
line.replace("\t",[""," "," "," "," "],添え字はtabSize-index%tabSize)
なんて書けたらいいんだけど・・。
ふぅ、頭の良くなる薬が欲しいもんだ。
2006/08/16 追記
仕様確認漏れで、最後の一行が出力されなくなっていたので修正。
Before
return lines.join("\n");
After
return lines.join("\n")+"\n";
なんでやねんと思いつつ・・。