performance.now()
function and measure the time before and after the execution of your functions. Here we look at how this is done, as well as analyze a number of pitfalls.now()
function that returns a DOMHighResTimeStamp object. This is a floating point number that reflects the current time in milliseconds, to the nearest thousandth of a millisecond. In itself, this number has little value for us, but the difference between the two measured values ​​describes how much time has passed.Date
object, it is also “monotonous”. If in a simple way: it is not affected by the system time correction. That is, by creating two copies of the Date
and calculating the difference between them, we will not get an accurate, representative idea of ​​how much time has passed.Date
- before and after the clock transfer, we get, for example, the difference "1 hour 3 seconds and 123 milliseconds." And when using two copies of performance.now()
- "3 seconds 123 milliseconds 456,789 thousandths milliseconds." We will not analyze this API in detail here; those who wish can refer to the article Discovering the High Resolution Time API .makeHash()
, which will be used further in the text. function makeHash(source) { var hash = 0; if (source.length === 0) return hash; for (var i = 0; i < source.length; i++) { var char = source.charCodeAt(i); hash = ((hash<<5)-hash)+char; hash = hash & hash; // Convert to 32bit integer } return hash; }
var t0 = performance.now(); var result = makeHash('Peter'); var t1 = performance.now(); console.log('Took', (t1 - t0).toFixed(4), 'milliseconds to generate:', result);
Took 0.2730 milliseconds to generate: 77005292
performance.now()
uses the function makeHash()
, whose value is assigned to the variable result
. So we calculate how long it took to execute this function, and nothing more. You can measure in this way: var t0 = performance.now(); console.log(makeHash('Peter')); // Bad idea! var t1 = performance.now(); console.log('Took', (t1 - t0).toFixed(4), 'milliseconds');
makeHash('Peter')
, as well as the duration of sending and outputting the result to the console. We do not know how long each of these operations takes, we only know their total duration. In addition, the speed of sending data and output to the console strongly depends on the browser and even on what else it does at that time. You probably think that console.log
is unpredictably slow. But in any case, it will be an error to perform more than one function, even if each of the functions does not imply any input-output operations. For example: var t0 = performance.now(); var name = 'Peter'; var result = makeHash(name.toLowerCase()).toString(); var t1 = performance.now(); console.log('Took', (t1 - t0).toFixed(4), 'milliseconds to generate:', result);
toLowerCase()
or toString()
. var t0 = performance.now(); for (var i = 0; i < 10; i++) { makeHash('Peter'); } var t1 = performance.now(); console.log('Took', ((t1 - t0) / 10).toFixed(4), 'milliseconds to generate');
Took 0.2730 milliseconds to generate: 77005292 Took 0.0234 milliseconds to generate: 77005292 Took 0.0200 milliseconds to generate: 77005292 Took 0.0281 milliseconds to generate: 77005292 Took 0.0162 milliseconds to generate: 77005292 Took 0.0245 milliseconds to generate: 77005292 Took 0.0677 milliseconds to generate: 77005292 Took 0.0289 milliseconds to generate: 77005292 Took 0.0240 milliseconds to generate: 77005292 Took 0.0311 milliseconds to generate: 77005292
performance.now()
very useful, because you get a value with which you can do anything. var numbers = []; for (var i=0; i < 10; i++) { var t0 = performance.now(); makeHash('Peter'); var t1 = performance.now(); numbers.push(t1 - t0); } function median(sequence) { sequence.sort(); // note that direction doesn't matter return sequence[Math.ceil(sequence.length / 2)]; } console.log('Median time', median(numbers).toFixed(4), 'milliseconds');
Array.prototype.indexOf
. function isIn(haystack, needle) { var found = false; haystack.forEach(function(element) { if (element.toLowerCase() === needle.toLowerCase()) { found = true; } }); return found; } console.log(isIn(['a','b','c'], 'B')); // true console.log(isIn(['a','b','c'], 'd')); // false
haystack.forEach
loop will haystack.forEach
through all the elements, even if we quickly found a match. We use the good old for: function isIn(haystack, needle) { for (var i = 0, len = haystack.length; i < len; i++) { if (haystack[i].toLowerCase() === needle.toLowerCase()) { return true; } } return false; } console.log(isIn(['a','b','c'], 'B')); // true console.log(isIn(['a','b','c'], 'd')); // false
function isIn1(haystack, needle) { var found = false; haystack.forEach(function(element) { if (element.toLowerCase() === needle.toLowerCase()) { found = true; } }); return found; } function isIn2(haystack, needle) { for (var i = 0, len = haystack.length; i < len; i++) { if (haystack[i].toLowerCase() === needle.toLowerCase()) { return true; } } return false; } console.log(isIn1(['a','b','c'], 'B')); // true console.log(isIn1(['a','b','c'], 'd')); // false console.log(isIn2(['a','b','c'], 'B')); // true console.log(isIn2(['a','b','c'], 'd')); // false function median(sequence) { sequence.sort(); // note that direction doesn't matter return sequence[Math.ceil(sequence.length / 2)]; } function measureFunction(func) { var letters = 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z'.split(','); var numbers = []; for (var i = 0; i < letters.length; i++) { var t0 = performance.now(); func(letters, letters[i]); var t1 = performance.now(); numbers.push(t1 - t0); } console.log(func.name, 'took', median(numbers).toFixed(4)); } measureFunction(isIn1); measureFunction(isIn2);
true false true false isIn1 took 0.0050 isIn2 took 0.0150
haystack.forEach
benefits from low-level optimization at the browser JS engine level, which is not done using an array index. So do not measure, do not know!performance.now()
, we found that our intuition could fail us: the empirical data did not completely coincide with our assumptions. If you want to write fast web applications, the JS code must be optimized. And since computers are practically living beings, they are still capable of being unpredictable and surprising us. So the best way to make your code faster is to measure and compare.performance.now()
tool. However, measuring the runtime is only one aspect. Performance is also affected by memory usage and code complexity.Source: https://habr.com/ru/post/272087/
All Articles