• 一个算法改进带来惊人效率


    几天前,应项目的要求开发了一个新的树控件.使用后,开发人员反应良好,效率有了质的提升. 其中一个核心算法如下:

        _generate_tree: function(pnode, items) {
            if (items.length === 0) return;
            var item, node, id, text, pid, level, checked;
            for (var i = items.length - 1; i >= 0; i--) {
                item = items[i];
                pid = item["parentid"];
                if (pid === pnode.id) {
                    id = item["id"];
                    text = item["text"];
                    level = pnode["level"] + 1;
                    checked = item["checked"];
                    node = new Node(id, pnode, text, level, checked);
                    pnode.add(node);
        
                    this.nodes[id] = node;
                    this.dataset[id] = item;
        
                    items = items.slice(0);
                    items.splice(i, 1);
                    arguments.callee.call(this, node, items);
    	    }
            }
       }
            
        

    用于生成树的存储结构如下:

    [{"id":"1","parentid":"0","text":"全网组织"},{"id":"58","parentid":"1","text":"asdfasdfdsa"},{"id":"2","parentid":"1","text":"商户组织"},{"id":"3","parentid":"1","text":"用户组织"},{"id":"4","parentid":"1","text":"运维部"},{"id":"64","parentid":"2","text":"nnnnn"},{"id":"65","parentid":"2","text":"vvvvv"},{"id":"63","parentid":"2","text":"mmmmm"},{"id":"55","parentid":"2","text":"vwfwefwef"},{"id":"61","parentid":"2","text":"tetetetetet"},{"id":"23","parentid":"2","text":"testtest"},{"id":"25","parentid":"2","text":"劳而无功"},{"id":"47","parentid":"2","text":"1313"},{"id":"46","parentid":"2","text":"12"},{"id":"48","parentid":"2","text":"14"},{"id":"43","parentid":"2","text":"5678"}]

    备注:用于生成树的存储结构是无序的.node是树的一个节点,有相应的属性及方法.
    这个构造树的函数可以很好的工作,思路也清晰明了.只是效率是 n! ,接**方级.
    一般现实使用中,用于生成树的数据都不会很多;很多的话,都是采用点击异步加载的方式来实现. 所以,测试人员也没有提出意见.
    我在作代码审查的时候,作了一个性能测试.用2000多条记录生成一个树.
    chrome下表现尚可, 稳定在160ms左右;在ie7,则达到了4s左右.OMG,这个简直无法令人接受.
    深思熟虑后,提供了一个改进后的算法.

        _generate_tree2: function(root, items) {
            if (items.length === 0) return;
            var self = this;
            var item, node, id, text, pid,rid = root.id, level, checked,dict = {};
        
            for (var i = items.length - 1; i >= 0; i--) {
                item = items[i];
                pid = item["parentid"];
                if( !dict[pid] ){
                    dict[pid] = [];
                }
                dict[pid].push(item);
            (function(pid,pnode) {
                var cs = dict[pid];
                if(!cs) return;
                for (var j = 0; j < cs.length; j++) {
                    item = cs[j];
                    id = item["id"];
                    text = item["text"];
                    level = pnode["level"] + 1;
                    checked = item["checked"];
                    node = new Node(id, pnode, text, level, checked);
                    pnode.add(node);
                    self.nodes[id] = node;
                    self.dataset[id] = item;
                    arguments.callee.call(self, node.id, node);
                
            })(rid,root);
         }
        

    这次测试后,在chrome下稳定在4ms左右,在ie7下则稳定在60ms左右.so perfect!
    效率基本接*是线性了. 哈.. 还能再改进吗? 大拿们.

  • 相关阅读:
    SPOJ ADAFIELD Ada and Field(STL的使用:set,multiset,map的迭代器)题解
    hdu 6444 网络赛 Neko's loop(单调队列 + 裴蜀定理)题解
    hdu6446 网络赛 Tree and Permutation(树形dp求任意两点距离之和)题解
    HDU6447 网络赛 YJJ's Salesman(DP + 线段树)题解
    HDU 6438 网络赛 Buy and Resell(贪心 + 优先队列)题解
    BZOJ 3155 Preprefix sum
    BZOJ 2743 采花
    BZOJ 3339 Rmq Problem
    BZOJ 1660 乱发节
    BZOJ 3531 旅行
  • 原文地址:https://www.cnblogs.com/ms_config/p/2124997.html
Copyright © 2020-2023  润新知