假设我的页面上有以下JS(compare
是一个与问题无关的简单比较函数):
function sortArray(a) {
a.sort(compare);
}
function sortJQuerySet(b) {
b.sort(compare);
}
$(document).ready(function(){
var a = [], b = [], i = 0, n = 1000;
for(i=0; i<n; ++i) {
a.push($('<div>' + i.toString() + '</div>'));
b.push($('<div>' + i.toString() + '</div>'));
}
b = $(b);
$('#runner').click(function(){
sortArray(a);
sortJQuerySet(b);
});
});
如您所见,a
和b
基本上是相同的数组,唯一的区别是b
变成了jQuery set
。我正在尝试对这两个数组进行排序并对排序进行分析。请注意,两个数组中的元素数量为1000。
以下是Safari中两个容器的排序分析结果:
Safari在1000个元素的jQuery集上进行 50万次比较。这看起来更像是二次排序,而不像 O(n log n)排序。与此同时,对原生数组进行排序就可以了。
对于两种容器类型,Chrome浏览器中的排序工作时间大致相同。
P.S。我使用了Safari 6.0.4,jQuery 1.7.1和jQuery 1.10.1。 代码:https://gist.github.com/ikostia/5925715
答案 0 :(得分:1)
关于WebKit引擎,或许this discussion可能会有所启发。
我觉得从这条线上看: 631 if(thisObj-&gt; classInfo()==&amp; JSArray :: s_info&amp;&amp;!asArray(thisObj) - &gt; inSparseMode()){只有非数组或数组 某种“稀疏”模式的排序效率低下。我不确定 稀疏模式是什么,但让我试试我的雷蒙德陈灵感的通灵 功率:如果指定[0] = 1和[1000000] = 2,则不需要1到 要存储999999,所以像这样的数组将以稀疏形式存在 模式,其功能更像是由整数键控的哈希表。该 同样适用于非阵列...
(上述引文中讨论的源代码是here)
现在让我们来看看jQuery source code。
调用$(someArrayOrSelectorString)
会导致调用init
方法(第43行)。
init方法返回jQuery.makeArray( selector, this )
,其中this
是jQuery的一个实例(如果我错了,请纠正我)。
最后,在makeArray
方法内部调用jQuery.merge
(第600行),它将使用传递的数组元素填充jQuery实例。
所以看起来包装数组导致类似数组的对象(jQuery实例),但不是真正的数组。 Safari将这个对象视为稀疏对象。
(你可能对this answer and comments感兴趣。这就是我借用这个想法的答案)