有关任务的一些信息:
我有一个函数(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。我的计算机上的数字略有不同(我通过节点执行代码)