Javascript 需要提高查找等于给定和的最早对的函数的性能

Javascript 需要提高查找等于给定和的最早对的函数的性能,javascript,arrays,Javascript,Arrays,我有一个接受数组和数字的函数。它扫描数组,查找数组中最早出现的两个数字,这两个数字加起来就是这个数字。我想知道,在性能方面,什么可以帮助这个功能运行得更快。它必须在6秒内处理大约10000000个项目的列表。我已经重构过几次了,但仍然没有实现 什么是速度最好的数组迭代方法?我认为for循环是最慢的,所以我选择了map。有没有更快的办法?每个() 注意:提供的数组可能有重复的、正数或负数(比如说现在最多1000000个) var low\u pair=函数(ints,s){ var lowNum=

我有一个接受数组和数字的函数。它扫描数组,查找数组中最早出现的两个数字,这两个数字加起来就是这个数字。我想知道,在性能方面,什么可以帮助这个功能运行得更快。它必须在6秒内处理大约10000000个项目的列表。我已经重构过几次了,但仍然没有实现

什么是速度最好的数组迭代方法?我认为for循环是最慢的,所以我选择了map。有没有更快的办法?每个()

注意:提供的数组可能有重复的、正数或负数(比如说现在最多1000000个)

var low\u pair=函数(ints,s){
var lowNum=ints.length,lowMatch,highNum,clone=[],i;
对于(i=0;iind?highNum=i:highNum=ind;
如果(高数值<低数值){
lowNum=highNum;
低匹配=[ints[i],ints[ind]];
}
}
});
}
返回低匹配;
};
什么是速度最好的数组迭代方法

看看吧。但是请注意,答案可能不推荐,而当前的引擎更擅长优化不同的东西。您应该始终在自己的目标环境中对自己进行基准测试

但是,您应该尝试改进算法,而不是寻找原始速度和微观优化。在您的情况下,只需在
i
处启动内部循环,就可以将函数的速度提高一倍,这样您就不会两次访问所有组合。此外,通过提前从函数返回,您可以加速平均情况(取决于您的数据)。要找到“最早的一对”,您不必遍历整个数组并计算最小值,只需这样做。如果数据是有序的(或者至少偏向于某种分布),您也可以利用这一点

我会用

function firstPair(ints, s) {
    var len = ints.length;
    for (var end = 0; end < len; end++)
        for (var i=0, j=end; i<end; i++)
            if (i != --j && ints[i]+ints[j] == s)
                return [i, j];
    for (var start = 0; start < len; start++)
        for (var i=start, j=len; i<len; i++)
            if (i != --j && ints[i]+ints[j] == s)
                return [i, j];
    return null;
}
函数第一对(ints,s){
var len=整数长度;
对于(var end=0;end对于(var i=0,j=end;i4]|=1而言,主要问题是当前函数的复杂度为O(n^2),对于10000000个元素数组来说太高了。map函数会遍历整个数组。因此,需要执行10000000*10000000=100万亿次“操作”。复杂性需要降低。我的最佳猜测->在线性循环中使用哈希表。下面是我的示例代码,其中最坏情况下测试了1000万个元素,在我的旧机器上运行了大约8秒。它只运行了1000万次,而不是100万亿次

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var low_pair = function (ints, s) {
    var found = {};
    var lowMatch;
    for (var i = 0; i < ints.length; i++) {
        var num = ints[i];
        var prevNum = s-num;
        if (found[prevNum] === true){
            if (prevNum>num){
                lowMatch = [num, prevNum];
            } else {
                lowMatch = [prevNum, num];
            }
            break;
        } else {
            found[num] = true;
        }
    }
    return lowMatch;
};
var test_array_size = 10000000;
var test_array = new Array(test_array_size);
for (var i=0;i<test_array_size;++i){
    test_array[i] = test_array_size-i;
}
console.log("Array initialized");
var start = new Date().getTime();
console.log(low_pair(test_array, 12));
var end = new Date().getTime();
console.log("Running time: "+(end-start)+" ms");
</script>
<head>
<body>
</body>
</html>

var low_pair=函数(整数,秒){
var-found={};
var低匹配;
对于(变量i=0;inum){
lowMatch=[num,prevNum];
}否则{
lowMatch=[prevNum,num];
}
打破
}否则{
发现[num]=true;
}
}
返回低匹配;
};
var测试数组大小=10000000;
var测试数组=新数组(测试数组大小);

对于(var i=0;i,此函数在0毫秒内始终运行50000000个项目数组:

var low_pair = function (s) {
var ints = [];
for(var i = 0; i < 50000000; i++) {
    ints.push(Math.floor(Math.random() * 9));
}
console.time('pair');
var counter = 1;
for (var i = 0; i < ints.length; i++) {
    var sum = ints[i] + ints[counter];
    if (i !== counter) {
        if (sum === s) {
            console.timeEnd('pair');
            return console.log([ints[i], ints[counter]]);
        }
    }
    if (i == counter) {
        counter++;
        i = -1;
    }
}
console.time('pair');
console.log( undefined);
};
var low\u pair=函数{
var ints=[];
对于(变量i=0;i<50000000;i++){
ints.push(Math.floor(Math.random()*9));
}
控制台时间('pair');
var计数器=1;
对于(变量i=0;i
我们将创建一个函数,返回最早的一对元素,这些元素相加为所需的总和:

function find_pair(l, s) {
    var min_indexes = {};
    for (var i = 0; i < l.length; i++) {
        var a = l[i];
        if ((s - a) in min_indexes)
            return [s - a, a];
        if (!(a in min_indexes))
            min_indexes[a] = i;
    }
}

你应该尝试for循环,以防万一;)。是的,我现在正在为不同的方法计时……我可能弄错了,但是你不是在用这段代码返回最新的一对吗?你永远不会破坏
for
循环,你不应该在给它赋值的地方返回
lowMatch
?(在这种情况下,
map
可能应该替换为一个循环,以允许它返回
low\u pair
函数范围内的内容)这还取决于数据的性质。是否存在重复项?它们是否分布均匀?它们是否都是积极的?等等。许多可能的优化都依赖于数据。你用“是”回答了@myfunkyside的问题“a”或“b”。是1+2,然后是2+3,然后是3+4,还是1+2,1+3,1+4等等……是的,没有找到……谢谢:找到配对([5, 9, 13, -3], 10)我假设数组有数字。不是吗?请注意,
操作符中的
非常慢。为什么你的数组不包含9?很好。这只是我输入的一个随机数。我用随机数高达99999重新测试了该函数,它在1ms时运行50mil。在不到100ms时,随机数高达1mil。当m数字达到10英里,性能开始下降。我得到了6秒和8秒的结果。
var low_pair = function (s) {
var ints = [];
for(var i = 0; i < 50000000; i++) {
    ints.push(Math.floor(Math.random() * 9));
}
console.time('pair');
var counter = 1;
for (var i = 0; i < ints.length; i++) {
    var sum = ints[i] + ints[counter];
    if (i !== counter) {
        if (sum === s) {
            console.timeEnd('pair');
            return console.log([ints[i], ints[counter]]);
        }
    }
    if (i == counter) {
        counter++;
        i = -1;
    }
}
console.time('pair');
console.log( undefined);
};
function find_pair(l, s) {
    var min_indexes = {};
    for (var i = 0; i < l.length; i++) {
        var a = l[i];
        if ((s - a) in min_indexes)
            return [s - a, a];
        if (!(a in min_indexes))
            min_indexes[a] = i;
    }
}
> var l = [2, 3, 4, 5, 5, 7, 8]
> find_pair(l, 10)
[5, 5]
> find_pair(l, 6)
[2, 4]
> find_pair(l, 5)
[2, 3]
> find_pair(l, 15)
[7, 8]
> find_pair([5, 9, 13, -3], 10)
[13, -3]