为循环性能问题加倍

woutr_be

对模糊的标题表示歉意,还不确定是否还能用其他方式来描述问题。

我最近遇到一种情况,我必须遍历对象数组以比较多个值,因此我选择在for循环中使用for循环来比较每个对象与其他每个对象。

尽管这在小型阵列上可以正常工作,但是一旦我的阵列变大(例如10,000个对象),性能就会成为一个大问题。

此数组包含以下类型的对象:

[{ char: '_', from: 0, to: 2, chrLength: 2 },
{ char: '_', from: 0, to: 7, chrLength: 7 },
{ char: 'a', from: 1, to: 3, chrLength: 2 },
{ char: 'a', from: 1, to: 6, chrLength: 5 },
{ char: '_', from: 2, to: 7, chrLength: 5 },
{ char: 'a', from: 3, to: 6, chrLength: 3 }]

我的想法是,我只能选择fromto之间不与任何其他对象重叠的对象。from并且to是另一个数组中的索引)

因此,对于示例数组,可能的结果将是:

[{ char: '_', from: 0, to: 2, chrLength: 2 },
 { char: 'a', from: 1, to: 3, chrLength: 2 },
 { char: 'a', from: 1, to: 6, chrLength: 5 },
 { char: 'a', from: 3, to: 6, chrLength: 3 }]

我的处理方式如下:

var canUse = true,
    posibilities = [];
for(i = 0; i < l; i++) {
    canUse = true;
    for(var j = 0; j < l; j++) {
        if((results[i].from < results[j].from && results[i].to > results[j].to)) {
            canUse = false;
            break;
        }
    }

    if(canUse) posibilities.push(results[i]);
}

看到较大的阵列的性能非常糟糕,我想知道是否有更好的解决方案?

尤里·塔拉班波(Yury Tarabanko)

这是想法(Demo):

  1. 您需要某种自平衡树来支持O(log n)的插入和删除操作。为了简单起见,我使用了红黑树。
  2. 您需要使用间隔的中点作为键,即(from + to)/2
  3. 假设您已经将k项目“插入”到树中并准备插入k+1您的步骤是:
  4. 如果k+1覆盖根-忽略它。
  5. 如果k+1根目录覆盖了-从树中删除根目录,然后再尝试一次。
  6. 否则,通过比较k+1的中部和根的中部,继续到左或右子树
  7. 插入所有内容后,遍历生成的树,收集每个节点。
  8. 利润...通过将其自身隐藏起来,我已经使用了4倍的阵列。我的计算机在Chrome下的结果是116ms(冷启动)和64ms(预热后)。

 function process() {
    console.log('Processing results of length: ' + l);

    console.time('Processing');

    var comparator = function(a, b) { //Comparator to build a tree
           return a.mid - b.mid;
        },
        isAinB = function(a, b) { //util function to check if a is inside b
            return b.from < a.from && b.to > a.to;    
        },
        rbtree = new RBTree(comparator), //Build an empty tree
        i = results.length - 1, item, posibilities = [];

    function check(root, x) { //Recursive checker
        var data;        

        if(!root) { //Either tree is empty or we've reached a leaf
            rbtree.insert(x);
            return;
        }

        data = root.data;

        if(isAinB(data, x)) { //4
            return;    
        }
        if(isAinB(x, data)) { //5
            rbtree.remove(data);
            check(rbtree._root, x);
            return;
        }    

        check(root[comparator(data, x) > 0 ? 'left' : 'right'], x); //6
    }

    for(; i >= 0; i--) { 
        item = results[i];
        item.mid = (item.from + item.to)/2; //2
        check(rbtree._root, item); //3
    }

    rbtree.each(function(item) { //7
        posibilities.push(item);
    });
    console.timeEnd('Processing');

    console.log(posibilities.length);
}

顺便说一句,我已经使用了RBTree实现不知道这是否是最好的:)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

循环性能下降

来自分类Dev

循环性能下降

来自分类Dev

循环性能的Javascript

来自分类Dev

Javascript 循环性能

来自分类Dev

Java中的Break vs Normal循环性能问题

来自分类Dev

java arrayList循环性能

来自分类Dev

Itertools与嵌套循环性能

来自分类Dev

WebGL渲染循环性能

来自分类Dev

Foreach 循环中的 For 循环性能改进

来自分类Dev

PHP:数组嵌套循环性能

来自分类Dev

while循环性能单核与多核机器

来自分类Dev

向量在C ++中的循环性能

来自分类Dev

gcc简单算术循环性能

来自分类Dev

使用openmp优化C for循环性能

来自分类Dev

Matlab代码嵌套循环性能改进

来自分类Dev

第一循环性能测试较慢

来自分类Dev

C ++实现基于循环和基于范围的循环性能

来自分类Dev

Python内置求和函数与循环性能对比

来自分类Dev

循环性能差,但顺序执行速度快

来自分类Dev

在无限循环性能中声明变量类型?

来自分类Dev

循环性能差异和编译器优化

来自分类Dev

在VBA Excel中优化双循环性能

来自分类Dev

在无限循环性能中声明变量类型?

来自分类Dev

使用项目宏时如何提高循环性能?

来自分类Dev

Java线程工作者组性能与嵌入式循环性能

来自分类Dev

cuda python GPU numbapro 3d循环性能不佳

来自分类Dev

奇怪的OpenCL调用C ++的副作用以提高循环性能

来自分类Dev

紧密循环性能下的2D阵列与阵列阵列C#

来自分类Dev

.NET x64中的for循环性能奇数:偶数迭代亲和力?