简体   繁体   English

处理大量数字时功能会变慢

[英]Function slows down when working with high numbers

I've wrote a script that instead of giving the real average of a set of data returns a windows that contains most data points. 我编写了一个脚本,而不是给出一组数据的真实平均值,而是返回一个包含大多数数据点的窗口。 Let me show some code: 让我显示一些代码:

time.tic()
var selectedAverage = 0;
var highestPointCount = 0;
for (var i = 1; (i*step) <= maxValue; i++) {
    var dataPointCount = 0;
    for (var j = 0; j < myArray.length; j++) {
        if (myArray[j] >= minValue+(i-1)*step && myArray[j] <= minValue+i*step) {
            dataPointCount++;
        }
    }
    if (dataPointCount > highestPointCount) {
        highestPointCount = dataPointCount;
        selectedAverage = (minValue+(i-1)*step)+Math.round(0.5*step);
    }
}
console.log(time.toct().ms) 
return selectedAverage;

First the step value is calculated by subtracting the minimum value from the maximum value and then deciding by 10. So there are 10 'horizontal' windows. 首先,通过从最大值中减去最小值然后确定10,来计算步长值。因此,有10个“水平”窗口。 Then the script counts the amount of datapoint within each window and returns a appropriate average. 然后,脚本会计算每个窗口内的数据点数量,并返回适当的平均值。

It appears however that script slows down extremely (sometimes more than 200 times) when an array of larger numbers is passed in (1.000.000 for example). 但是,当传入一个较大的数字数组(例如1.000.000)时,脚本会非常慢(有时超过200倍)。 Array lengths are roughly 200 but always the same length so it must be associated with the actual values. 数组的长度大约为200,但总是相同的长度,因此必须与实际值相关联。 Any idea where it is going wrong? 知道哪里出了问题吗?

EDIT: The code to get the step value: 编辑:获得步骤值的代码:

var minValue = myArray.min();
var maxValue = myArray.max();
var step = Math.round((maxValue-minValue)/10);
if (step === 0) {
    step = 1
}

The .min() and .max() are prototypes attached to Array. .min()和.max()是附加到Array的原型。 But this all goes very fast. 但这一切进行得非常快。 I've measured every step and it is the for loop that slows down. 我已经测量了每个步骤,并且for循环变慢了。

There are 2 different things I think of your issue: 我想到您的问题有两件事:

  1. Removed unnecessary / repeated calculation 删除了不必要的/重复的计算

Inside your nested code you have minValue+(i-1)*step and minValue+i*step calculated everytime for the same value of minValue , i and step . 在嵌套代码中,每次都为minValueistep的相同值计算minValue+(i-1)*stepminValue+i*step step You should pull it up before the 2nd for-loop where it becomes: 您应该在第二个for循环之前将其上拉:

var dataPointCount = 0;
var lowerLimit = minValue+(i-1)*step;
var higherLimit = minValue+1*step;
for (var j = 0; j < myArray.length; j++) {
    if (myArray[j] >= lowerLimit && myArray[j] <= higherLimit) {
        dataPointCount++;
    }
}
  1. You got severe performance hit when you are handling big data array are likely caused by memory swapping. 当您处理大数据阵列时,可能会由于内存交换而导致性能严重下降。 From your point of view you are dealing with a single array instance, however when you have such a big array it is unlikely the JavaScript VM has access to consecutive memory space to hold all those values. 从您的角度来看,您正在处理单个数组实例,但是,当您拥有如此大的数组时,JavaScript VM不太可能访问连续的内存空间来保存所有这些值。 It is very likely JavaScript VM has to juggle multiple memory blocks that it gets from the operating system and have to spend extra effort to translate which value is where during reading/writing. JavaScript VM很可能必须处理从操作系统中获得的多个内存块,并且必须花费额外的精力来转换在读/写期间哪个值在哪里。

If I understood your algorithm correctly, this should remove all unnecesary calculations and be much faster: 如果我正确理解了您的算法,这应该删除所有不必要的计算,并且速度要快得多:

var arr = [];
var maxQty=0;
var wantedAverage = 0;
for (var j = 0; j < 11; j++) {
    arr[j]=0;
}
for (var j = 0; j < myArray.length; j++) {
    var stepIndex = Math.floor((myArray[j]-minValue)/step)
    arr[stepIndex]+=1;

    if(arr[stepIndex] > maxQty ){
        wantedAverage = minValue + stepIndex*step +Math.round(0.5*step);
        maxQty = arr[stepIndex]
    }
}
console.log(maxQty, wantedAverage)

We just iterate over each element of the array only once, and calculate the index of the window it belongs to, adding one to the quantity array. 我们只对数组的每个元素进行一次迭代,然后计算它所属的窗口的索引,将一个添加到数量数组。 Then we update the wantedAverage if we have a bigger amount of points in window found 然后,如果我们在窗口中发现了更多的点,我们将更新wantedAverage

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM