如何提高速度(为什么运行这么慢)?

时间:2020-05-14 14:55:30

标签: javascript arrays performance math

有关任务的一些信息:
我有一个函数(js),该函数接受一个参数并返回由数学公式计算出的值

var f = function(x) {
    return 3 * Math.sin(2 * x) * Math.pow(Math.cos(x), 4);
}

我还有一个数组,索引是间隔号(从头开始索引),按索引的元素值是该值落入该索引的次数。

例如,如果我在数组中有2个元素,而我感兴趣的值是从0到1,则如果f(x)返回的数字小于0.5,则数组的第一个元素增加加1,如果大于0.5,则第二个元素相应增加1。

我修改了函数,以便它立即返回带有此参数的值将落入的间隔的编号。

var hist_min = 0;
var hist_max = 2;
var hist_range = hist_max-hist_min;
var hist_cols = 30;

var f = function(x) {
    return Math.floor(((3 * Math.sin(2 * x) * Math.pow(Math.cos(x), 4) -hist_min) / hist_range) * 
    hist_cols);
}

在上面的示例中,我有30个间隔,最左边的左边框是0,右边是2。

接下来,我测量该函数3 * 10 ^ 6次迭代的执行速度。

var iteratitions = 3000000;

var start_time = Date.now ();
for (var i = 0; i < iteratitions; i ++) {
    var need_col = f(Math.random())
}
console.log("Finished in", Date.now() - start_time + "ms")

结果很快,在我的计算机上大约100-200ms

但是,我需要以某种方式将这些间隔保存到一个数组中。

我这样做

var start_time = Date.now();

for (var i = 0; i < iteratitions; i ++) {
    var need_col = f(Math.random())
    arr[need_col]++;
}

console.log ("Finished in", Date.now () - start_time + "ms")

但是,这已经花费了更长的时间〜1300ms

起初,我以为是因为arr[need_col]++花了很长时间才能完成,但是,如果我这样做的话:

for (var i = 0; i < iteratitions; i ++) {
    var need_col = f(Math.random())
    var need_col2 = 3
    arr[need_col2]++;
}

它已经运行了约130毫秒

问题是,为什么如果我仅将函数f的值保存到Need_col变量中,那么一切都会快速进行,并且一旦使用变量Need_col(将其作为索引传递),一切都会有时变慢?

我带了所有代码

var hist_min = 0;
var hist_max = 2;
var hist_range = hist_max-hist_min;
var hist_cols = 30;

var need_col = 0;

/*
var f = function(x) {
	return 3*Math.sin(2*x)*Math.pow(Math.cos(x), 4)
}
*/

var f = function(x) {
	return  Math.floor(((3*Math.sin(2*x)*Math.pow(Math.cos(x), 4)-hist_min)/hist_range) * hist_cols);
}

var iteratitions = 3000000;
var arr = [];

// инициализация
for (var i=0; i < hist_cols; i++) {
	arr.push(0)
}

// пустой цикл занимает время
var start_time = Date.now();

for (var i=0; i < iteratitions; i++) {
}
console.log("empty loop finished in",Date.now()-start_time+"ms")


// просто увеличение элемента массива по индексу
var start_time = Date.now();

for (var i=0; i < iteratitions; i++) {
	var need_col = 3
	arr[need_col]++;
}
console.log("arr[need_col]++; Finished in",Date.now()-start_time+"ms")


// просто выполение f(x) 
var start_time = Date.now();

for (var i=0; i < iteratitions; i++) {
	need_col = f(Math.random())
	//var need_col2 = 3
	//arr[need_col2]++;
}
console.log("just f(x) finished in",Date.now()-start_time+"ms")
//console.log(need_col)

// заполнение массива тем, что нам нужно
var start_time = Date.now();

for (var i=0; i < iteratitions; i++) {
	var need_col = f(Math.random())
	if (need_col > 0 && need_col < hist_cols) {
		arr[need_col]++;
	}
	
}
console.log("filling array f(x) finished in",Date.now()-start_time+"ms")

console.log("arr=", arr)

P.S。我的计算机上的数字略有不同(我通过节点执行代码)

my console output

0 个答案:

没有答案