JQuery Sucks (Live版) —— 记一次20min的优化

这篇黑的有点丧心病狂了,其实问题基本上都在我自己。但光看结果的话,确实可以总结为:因为替换了一个jquery的方法调用,一下子把1.8s的执行时间优化到了18ms。

1.8s的方法原来是长这个样子的:

function recur($this, $arr) {
	if (blahblah) {
		return $arr;
	}
	else{
		return recur($this.next(), $arr.add($this));
	}
}
recur($whatever, $());

思路很简单,就是递归查找,中标的元素放到结果集里。开始想用[]来做结果集的,但随手搜了一下,发现jquery有个add的api,似乎用起来灰常爽的样子(后面的处理就直接可以在$arr.了),毫不犹豫的构造了个jquery大对象出来(潜意识觉得会慢,但又觉得不会慢到哪里去)。

跑了一下,WTF,1.8s!count一下,总用就500个dom的样子,这不科学!打开chrome profile,果然是recur方法占了大部分时间,再展开一看有个叫xxxDomComparexxx的function似乎是罪魁祸首。等等,为啥会有dom比较?

看了代码,问题就出在了jquery.add上,因为jquery会保证如果是包装的是一个dom集合的话,里面的元素一定是唯一的。所以,每add一个对象进去,都会触发一次uniquesort,复杂度N一下子就成了N*M(Sizzle.uniqueSort的复杂度不会算 =.=)。

该回[]:

function recur($this, arr) {
	if (blahblah) {
		return arr;
	}
	else{
		arr.push($this);
		return recur($this.next(), arr);
	}
}
recur($whatever, []);

18ms搞定。

本着科学务实的精神,我还有个进一步的猜想:是不是dom元素的==会比普通的==更慢?测试结果如下http://jsperf.com/dom-equal

慢,但根本没慢多少。

反正都是jq的错,黑完收工。