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


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

        _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!
    效率基本接*是线性了. 哈.. 还能再改进吗? 大拿们.

  • 相关阅读:
    如何给博客园添加背景canvas线条动画背景
    过去-现在-未来
    如何将图片转化为代码图片
    css3炫酷登录页面
    图片跟随鼠标移动特效
    css3实现鼠标移入图片特效
    在线上传图片获取url
    《程序员修炼之道:从小工到专家》读后感01
    动手动脑-随机数和重载
    JAVA学习第三周
  • 原文地址:https://www.cnblogs.com/ms_config/p/2124997.html
Copyright © 2020-2023  润新知