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