I found several articles on the Internet and questions here about how to measure the code performance in Node. But I got results that differ by about two times, depending on the measurement tool.
Target function is:
let arr = [75, 283, 361, 168, 23, 489, 421, 95, 72, 380, 384, 470, 235, 465, 276, 26, 364, 416, 373, 184, 211, 239, 485, 18, 19, 252, 447, 6, 291, 324, 497, 352,
458, 201, 238, 116, 333, 163, 207, 417, 340, 431, 5, 269, 258, 178, 182, 295, 257, 434, 37, 372, 154, 223, 313, 80, 71, 229, 379, 181, 396, 281, 491, 58, 254,
359, 79, 175, 143, 214, 217, 148, 393, 246, 34, 166, 251, 381, 413, 180, 338,
442, 494, 378, 123, 118, 395, 446, 459, 472, 457, 51, 127, 351, 389, 157, 260,
370, 405, 346]
const { performance } = require("perf_hooks")
function summBrute(arr, k) {
for(let i = 0; i < arr.length; i++) {
for(let j = i + 1; j < arr.length; j++) {
if(arr[i] + arr[j] == k) {
return true;
}
}
}
return false;
}
And measurement methods are:
console.time('summBrute')
summBrute(arr, 394)
console.timeEnd('summBrute')
var t0 = performance.now()
summBrute(arr, 394) //
var t1 = performance.now()
console.log("Call to summBrute took " + (t1 - t0) + " milliseconds.")
Here I want to find out whether there are two numbers in the array in question, add which, I get the second argument of the called function. I use these two methods independently of each other, just commenting out the corresponding section of the code. console.time() gives an average 0.300ms performance score console.time result
and performance.now() gives 0.170ms performance.now result
Please help me to understand why particular THESE two methods give different results (almost doubled)? I am using Node v15, CPU Core i5, 8GB RAM, Win10.
If you put the measurements in a small loop, you will see that they are barely consistent with themselves.
for(let i=0;i<5;i++){
console.time('summBrute')
summBrute(arr, 394)
console.timeEnd('summBrute')
var t0 = performance.now()
summBrute(arr, 394) //
var t1 = performance.now()
console.log("Call to summBrute took " + (t1 - t0) + " milliseconds.")
}
Produces
summBrute: 0.234ms
Call to summBrute took 0.1938999891281128 milliseconds.
summBrute: 0.171ms
Call to summBrute took 0.13520002365112305 milliseconds.
summBrute: 0.107ms
Call to summBrute took 0.1332000494003296 milliseconds.
summBrute: 0.095ms
Call to summBrute took 0.10259997844696045 milliseconds.
summBrute: 1.385ms
Call to summBrute took 0.10839998722076416 milliseconds.
they are almost random numbers, useless.
However if I call summBrute() 10 million times:
for(let i=0;i<5;i++){
console.time('summBrute')
for(let j=0;j<10000000;j++)
summBrute(arr, 394)
console.timeEnd('summBrute')
var t0 = performance.now()
for(let j=0;j<10000000;j++)
summBrute(arr, 394) //
var t1 = performance.now()
console.log("Call to summBrute took " + (t1 - t0) + " milliseconds.")
}
The results stop depending on the mood of my computer and become much more consistent:
summBrute: 16.369s
Call to summBrute took 16184.267899990082 milliseconds.
summBrute: 15.643s
Call to summBrute took 15852.86260008812 milliseconds.
summBrute: 16.355s
Call to summBrute took 15942.392500042915 milliseconds.
summBrute: 16.190s
Call to summBrute took 16314.965299963951 milliseconds.
summBrute: 16.523s
Call to summBrute took 16744.983800053596 milliseconds.
It still has a spread of almost half seconds, but it's pretty visible that the average (of 10 million calls) is around 16 seconds, and thus one call is around 0.016 ms, which is clearly not what any of the individual calls measured.
TL;DR: time is time, it matters far more what you measure than the timer API you pick.
Related
var counts = [2, 33, 61, 92, 125, 153, 184, 215, 245, 278, 306, 335, 365],
goal = 35;
let min = Math.min(...counts.filter(num => num >= goal));
console.log(min)
This works but in case goal=400, I will get 365 back as it's the last number in the array
You could find the wanted value or take the value at last index.
const
find = (array, value) => array.find((v, i, { length }) =>
v >= value || i + 1 === length
),
counts = [2, 33, 61, 92, 125, 153, 184, 215, 245, 278, 306, 335, 365];
console.log(find(counts, 35));
console.log(find(counts, 400));
A slightly different approach by taking the last item, if undefined.
const
find = (array, value) => array.find(v => v >= value) ?? array.at(-1),
counts = [2, 33, 61, 92, 125, 153, 184, 215, 245, 278, 306, 335, 365];
console.log(find(counts, 35));
console.log(find(counts, 400));
This will give you the smallest number above the goal, or the largest number in counts if there are no numbers above the goal
const counts = [2,33,61,92,125,153,184,215,245,278,306,335,365]
goal = 35;
const above_goal = counts.filter(num => num >= goal)
const min = above_goal.length === 0 ? Math.max(counts) : Math.min(above__goal)
console.log(min)
I am trying to find the best way to generate an array that has the following output:
[135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 275, 276, 277 , 278, 279, 280, 281, 282, 283, 284, 285, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 675, 676, 677, 678, 679, 700, 701, 702, 703, 704, 705 ...
As you can see it has a set of limits from 140 - 280 - 420 - 560 - 700 ( adds 148 to each value)
and then there's an interval with minus 5 and plus 5 for each value.
I already tried this approach
scrollFrom = Array.from(Array(bytesIndexTo).keys()).map(i => 140 + i * 140);
That returns me:
[140, 280, 420, 560, 700, ...
However I also need the plus and minus 5 values intervals...
I also noticed it uses to much resources.
const prev = [
[135,136,137,138,139],
[275,276,277,278,279],
];
const after = [
[141,142,143,144,145],
[281,282,283,284,285],
];
for (let i = 0; i < scrollFrom.length; i++) {
scrollFrom.push( scrollFrom[i] );
}
The purpose of this array is to have a set of values that will help me to identify a certain scroll position in order to execute a function, the addition of this intervals will help me to figure the scroll position even if the user scrolls fast.
Maybe I could load the values inside a .json and load them ?
What do you think ? thanks in advance
Once you create an array of central values (eg [140, 280, 420, 560, 700]), you can use flatMap to iterate over each item and construct another array of the 5 values below and above it:
const bytesIndexTo = 4;
const result = Array.from(
{ length: bytesIndexTo },
(_, i) => (i + 1) * 140
)
.flatMap(num => Array.from(
{ length: 11 },
(_, j) => num - 5 + j
));
console.log(result);
So, if you all you really want to do is to be able to test if a number is within 5 of a sentinel multiple, then I don't think you really want to be generating a giant array and using .includes(). That would be slow. If you were going to pre-generate values, you should use a Set and then use .has() which should be a lot faster than .includes() for a large set of data.
But, it seems to be that you can just calculate a lot faster without doing any pre-generation at all.
In the code below, we divide by the multiple (140) and then look at the remainder. If the remainder is <=5 or >= 135, then it's within 5 of the multiple, otherwise not. It's really that simple. Since it appears you don't want the numbers 0-5 (around the zero multiple) to be counted as true, we add a special case for those.
// tests to see if a value is within 5 of a multiple of 140
const multiple = 140;
const over = 5;
const below = multiple - over;
function testValue(val) {
if (val < below) return false;
const delta = val % multiple; // divide by multiple, get remainder
return (delta <= over || delta >= below); // see if remainder in right range
}
// run some tests on numbers at edges of the interval ranges
[
0, 1,
134, 135, 140, 144, 145, 146, // around 140
274, 275, 280, 284, 285, 286, // around 280
414, 415, 420, 424, 425, 426, // around 420
554, 555, 560, 564, 565, 566 // around 560
].forEach(num => {
console.log(`${num}: ${testValue(num)}`);
});
My aim is to hook up a midi device to my computer to create and manipulate shapes in p5.js. I'm still learning code so have a few questions regarding arrays and keys.
Is there a way to say if any of the values in noteC, noteE and noteG are triggered then 'something happens'?
But in a sort of combo as that is a chord as a opposed to say noteD and noteE which is not a chord.
Essentially I am trying to manipulate the shapes via chords being played but I am unaware of if "noteC + noteE + noteG" would do anything.
For example:
var noteC = [24, 36, 48, 60, 72, 84, 96, 108]
var noteE = [28, 40, 52, 64, 76, 88, 100]
var noteG = [31, 43, 55, 67, 79, 91, 103]
function keyPressed();
if (value ===noteC, noteE, noteG) {
ellipse(200, 200, 25, 30);
ellipse(200, 200, 50, 60);
ellipse(200, 200, 100, 100);
To do it without chords I imagine it would go something like:
function keyPressed() {
if (value ===36) {
ellipse(200, 200, 25, 30);
} else if (value === 40) {
ellipse(200, 200, 50, 60);
}
}
However manually transforming shapes separately away from any combination of chords feels static and I would like there to be a relationship between the manipulation if a chord is being played.
I would like it so that the scale of the ellipse is determined by the velocity of the keys being played but if it is part of a chord the x and y parameters will be the same.
Not asking for someone to do the code but if anyone could help me understand or point me in the right direction that would be great!
Thanks!
I have a little bit hard question, but I try to explain it:
So, I have 2 arrays. First array - array of cities. The second is the matrix with distances between this cities;
var cities = ['Gamburg', 'Dresden', 'Berlin', 'Bayern', 'Dortmund'];
var distanceMatrix = [
[0, 131, 523, 251, 600],
[131, 0, 785, 123, 541],
[252, 785, 0, 241, 741],
[251, 123, 241, 0, 632],
[600, 541, 741, 632, 0]
];
I need to generate a train with randomly choosen department and arrival point, with is not a problem. The problem is how to connect this 2 points with distance matrix correctly. If its possible. For example: distance between cities[1] and cities[3] accords to distanceMatrix[1][3] etc. So I need a function which randomly pick 2 towns and show distance between them according to distanceMatrix.
P.S. 2 days of hard mind work, and all I've done - is just 5 switch() functions, which is wrong way to complete this task.
Thank you !
You could take Array#indexOf for getting the index as accessor for the matrix.
var cities = ['Gamburg', 'Dresden', 'Berlin', 'Bayern', 'Dortmund'],
distances = [[0, 131, 523, 251, 600], [131, 0, 785, 123, 541], [252, 785, 0, 241, 741], [251, 123, 241, 0, 632], [600, 541, 741, 632, 0]];
function getDistance(city1, city2) {
return distances[cities.indexOf(city1)][cities.indexOf(city2)];
}
console.log(getDistance('Dresden', 'Berlin'));
console.log(getDistance('Dortmund', 'Bayern'));
An advanced solution could use an object with the indices.
var cities = ['Gamburg', 'Dresden', 'Berlin', 'Bayern', 'Dortmund'],
indices = { Gamburg: 0, Dresden: 1, Berlin: 2, Bayern: 3, Dortmund: 4 },
distances = [[0, 131, 523, 251, 600], [131, 0, 785, 123, 541], [252, 785, 0, 241, 741], [251, 123, 241, 0, 632], [600, 541, 741, 632, 0]];
function getDistance(city1, city2) {
return distances[indices[city1]][indices[city2]];
}
console.log(getDistance('Dresden', 'Berlin'));
console.log(getDistance('Dortmund', 'Bayern'));
Well, if I understood the problem correctly, you look for a way to form and access the matrix.
Let's first see the problem as indexes.
var cities = ['Gamburg', 'Dresden', 'Berlin', 'Bayern', 'Dortmund'];
cities[0] = Gamburg, cities[1] = Dresden, and so on.
The question is how to pick to cities at random and return the distance between the two.
function randomCities() {
while(true)
{
//Let's generate a random number between 0 and 4.
var randomCity_A = Math.floor((Math.random() * 4) + 0);
var randomCity_B = Math.floor((Math.random() * 4) + 0);
// add a condition that cities are not the same
if ( randomCity_A != randomCity_B){
var distance = distanceMatrix[randomCity_A][randomCity_B];
return "Distance between " + cities[randomCity_A] +" and " +
cities[randomCity_A] +": "+distance;
}
}
}
console.log(randomCities());
console.log(randomCities());
Hey :) You can subtract as example 35% from a number with methods like this:
var valueInString = "2383";
var num = parseFloat(valueInString);
var val = num - (num * .35);
console.log(val);
But how is it possible to randomize the .35/0.35 part?
As example if I would try:
var randomREAL = require('randomize');
var randomARR = [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75]
// randomREAL(randomARR) will generate a random number between 30 - 75 so that I can randomize my percentage value between 30% & 75%
var valueInString = "2383";
var num = parseFloat(valueInString);
var val = num - ( num * 0.randomREAL(randomARR) );
console.log(val);
I canĀ“t use
0.randomREAL(randomARR)
or
.randomREAL(randomARR)
Also If I would build a string like
var test = randomREAL(randomARR)
0.test
it would not work.
Any ideas how to randomize the percentage value ?
+("0."+randomARR[ Math.floor( randomARR.length * Math.random() ) ])
As youve pointed out
Also If I would build a string like
var test = randomREAL(randomARR)
0.test
it would not work.
Because 0. is not a string. You want string concatenation e.g.:
"0."+35
And then you need to parse it back into a number, which can be done with the unary plus operator :
+("0."+35)
Additionally if the number is always two digits, you can also use /100...
Hint: To get a random integer between 30 and 75 is as easy as:
30 + Math.floor( Math.random() * ( 75 - 30 ))
To easily get random numbers between an interval you can use this very simple function from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
}