为什么在Safari中对jQuery集合进行排序需要更多时间?

时间:2013-07-04 07:51:58

标签: javascript jquery performance safari

假设我的页面上有以下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);
        });
    });

如您所见,ab基本上是相同的数组,唯一的区别是b变成了jQuery set。我正在尝试对这两个数组进行排序并对排序进行分析。请注意,两个数组中的元素数量为1000。

以下是Safari中两个容器的排序分析结果: enter image description here

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

1 个答案:

答案 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感兴趣。这就是我借用这个想法的答案)