【问题标题】:jQuery sort function performancejQuery排序功能表现
【发布时间】:2009-10-07 11:53:44
【问题描述】:

我正在对

  • 元素的列表进行排序。我在一个我现在无法链接的页面上调整了一个功能。你可以看到现场直播here。点击“排序和筛选”,点击任意排序方式(英文名称、材料、状态...)。各种本质上都是一样的,所以CPU时间是一样的。

    我的 jQuery 函数如下所示:

    jQuery.fn.sort = function() {
        return this.pushStack([].sort.apply(this, arguments), []);
    };
      function sortAscending1(a, b)  { return $(a).find(".english").text() > $(b).find(".english").text() ? 1 : -1; };  
      function sortDescending1(a, b)  { return $(a).find(".english").text() < $(b).find(".english").text() ? 1 : -1; };
    

    我从下面的 jQuery 行调用它(s_alf_eng 是页面上的一个 clicable div)。

    $(document).ready(function() {
        $(".s_alf_eng").toggle(
            function() {
                $('.media-status-specie li').sort(sortAscending1).appendTo('.media-status-
            },
            function() {
                $('.media-status-specie li').sort(sortDescending1).appendTo('.media-status-specie');
            }); 
    

    我可以快速提供任何额外的说明。 谢谢!

    编辑:问题是对大列表执行这种排序需要几秒钟。在我的 core2duo 中,可能需要 20 秒!我将 find(".english") 更改为 filter(".english") ,速度似乎是一样的。关于如何加快速度的任何想法?

  • 【问题讨论】:

    • 有什么问题?代码使用 JavaScript 原生排序算法,我相信它几乎总是快速排序。
    • 对不起,我忘记添加了!!这是最大的列表(家庭),当然也是最慢的:ibc.lynxeds.com/family/tyrant-flycatchers-tyrannidae
    • Opera 会显示一条消息,让您知道排序正在进行中,但 FF、IE 等仅在排序完成时显示该消息。这是一个相关的问题:stackoverflow.com/questions/1531064

    标签: jquery performance sorting


    【解决方案1】:

    在内存中复制一份列表并对其进行排序,然后将现有列表替换为已排序的列表。这比操作实时、可见的 DOM 元素要快。

    【讨论】:

    • 您的意思是让列表出现 4 或 5 次(每种排序一次),然后只是切换它们的显示?这可能是一种选择,但我想知道它是否会使页面更重。
    • 我在keytosavannah.com/listings/browse/category/things_to_do 的多达 500 个企业列表中使用了这种技术。 Javascript 被缩小了,但基本上我在页面加载时将数据推送到一个数组中,并根据分页的需要将其打印到结果 div。这种方法的缺点是,除非您做出其他安排,否则您无法向搜索引擎蜘蛛展示任何内容。
    • 不,不为每个排序创建一个副本。当需要排序时,动态创建副本。或者,在内存中创建单个副本并在需要排序时使用它。但是,如果列表可以动态更改,那将导致复杂性。
    • 我想我明白了。我现在正在做的是对可见元素进行排序。因此,按 a 排序,然后按 b,然后按 a,然后按 b……总是需要相同的时间。即时创建副本,然后(排序后)隐藏原始副本并显示新创建的副本。在排序 a、排序 b、排序 a.. 之间切换与隐藏包含所有
    • 元素的 div 一样快。这就是重点?
  • 它会更快,因为不会有浏览器在每次迭代时更新可见页面的额外开销。价格是用于保存副本的内存。注意 - 您将删除旧列表并在其位置插入新列表,而不仅仅是隐藏旧列表(除非它的顺序已针对您的排序算法进行了优化)。
  • 【解决方案2】:

    我认为,如果您将名称作为元数据添加到节点中,并且在每次比较时无需查看 DOM,它会快得多。记住,毕竟有 O(n2) 个。

    $(function() { 
        $('.media-status-specie li')
            .each(function () {
                $(this).data('name', $(this).find(".english").text());
            })
    });
    
    .... 
    
    function sortDescending1(a, b)  { 
        return $(a).data('name') < $(b).data('name') ? 1 : -1; 
    }
    

    免责声明:我的看法是,我不擅长猜测慢点,就像其他任何开发人员一样,使用分析器来寻找真正的性能杀手。

    【讨论】:

    • 这要快得多!我有 5 种不同的类型(10 个功能)。我想我可以解析所有列表并填充更多变量,例如: .each(function () { $(this).data('english', $(this).find(".english" ).text()); $(this).data('scientific', $(this).find(".scientific").text()); $(this).data('total', $(this ).find(".total-material").text()); }) 这会增加页面的内存吗?最大页面少于 500 个
    • 元素。
  • 肯定会增加内存消耗。虽然不确定这是否会成为问题,但这在很大程度上取决于浏览器。您必须进行一些实验才能找到答案。
  • 顺便说一句,您可以分配任何类型的值,因此 data('sorting params', {english: 'name', science: 'bird'}) 也可以。
  • 已经上线了!它的表现要好得多。它甚至在 IE6 上运行良好 :) 非常感谢!
  • 猜你喜欢
    相关资源
    最近更新 更多
    热门标签