Bla*_*mba 5 javascript performance performance-testing node.js
如下面的代码所示,当我增加字符串的大小时,它导致0毫秒的差异。此外,随着字符串数的增加,存在不一致的情况。
我在这里做错什么了吗?
let stringIn = document.getElementById('str');
let button = document.querySelector('button');
button.addEventListener('click', () => {
let t1 = performance.now();
functionToTest(stringIn.value);
let t2 = performance.now();
console.log(`time taken is ${t2 - t1}`);
});
function functionToTest(str) {
let total = 0;
for(i of str) {
total ++;
}
return total;
}Run Code Online (Sandbox Code Playgroud)
<input id="str">
<button type="button">Test string</button>Run Code Online (Sandbox Code Playgroud)
我也尝试使用await,但结果是相同的(请参见下面的代码段)。包含以下代码的函数是async:
let stringArr = this.inputString.split(' ');
let longest = '';
const t1 = performance.now();
let length = await new Promise(resolve => {
stringArr.map((item, i) => {
longest = longest.length < item.length ? longest : item;
i === stringArr.length - 1 ? resolve(longest) : '';
});
});
const diff = performance.now() - t1;
console.log(diff);
this.result = `The time taken in mili seconds is ${diff}`;
Run Code Online (Sandbox Code Playgroud)
我也尝试将这个答案当作,但是也不一致。
作为一种解决方法,我尝试使用console.time功能,但是它不允许渲染时间,而且也不准确。
更新:我想构建一个类似于jsPerf的接口,该接口将与之非常相似,但用途不同。通常,我想比较取决于用户输入的不同功能。
There are 3 things which may help you understand what happening:
Browsers are reducing performance.now() precision to prevent Meltdown and Spectre attacks, so Chrome gives max 0.1 ms precision, FF 1ms, etc. This makes impossible to measure small timeframes. If function is extremely quick - 0 ms is understandable result. (Thanks @kaiido) Source: paper, additional links here
Any code(including JS) in multithreaded environment will not execute with constant performance (at least due to OS threads switching). So getting consistent values for several single runs is unreachable goal. To get some precise number - function should be executed multiple times, and average value is taken. This will even work with low precision performance.now(). (Boring explanation: if function is much faster than 0.1 ms, and browser often gives 0ms result, but time from time some function run will win a lottery and browser will return 0.1ms... longer functions will win this lottery more often)
There is "optimizing compiler" in most JS engines. It optimizes often used functions. Optimization is expensive, so JS engines optimize only often used functions. This explains performance increase after several runs. At first function is executed in slowest way. After several executions, it is optimized, and performance increases. (should add warmup runs?)
I was able to get non-zero numbers in your code snipet - by copy-pasting 70kb file into input. After 3rd run function was optimized, but even after this - performance is not constant
time taken is 11.49999990593642
time taken is 5.100000067614019
time taken is 2.3999999975785613
time taken is 2.199999988079071
time taken is 2.199999988079071
time taken is 2.099999925121665
time taken is 2.3999999975785613
time taken is 1.7999999690800905
time taken is 1.3000000035390258
time taken is 2.099999925121665
time taken is 1.9000000320374966
time taken is 2.300000051036477
Run Code Online (Sandbox Code Playgroud)
Explanation of 1st point
Lets say two events happened, and the goal is to find time between them. 1st event happened at time A and second event happened at time B. Browser is rounding precise values A and B and returns them.
Several cases to look at:
A B A-B floor(A) floor(B) Ar-Br
12.001 12.003 0.002 12 12 0
11.999 12.001 0.002 11 12 1
Run Code Online (Sandbox Code Playgroud)
浏览器比我们想象的更聪明,在内存分配、可重复代码执行、按需 CPU 分配等方面有很多改进和缓存技术。例如,V8(为 Chrome 和 Node.js 提供支持的 JavaScript 引擎)会缓存代码执行周期和结果。此外,您的结果可能会受到浏览器在代码执行时使用的资源的影响,因此即使有多个执行周期,您的结果也可能会有所不同。
正如您所提到的,您正在尝试创建 jsPerf 克隆,请查看Benchmark.js,该库由 jsPerf 开发团队使用。
运行性能分析测试非常困难,我建议在具有预定义和预分配资源的 Node.js 环境中运行它们,以获得结果。
| 归档时间: |
|
| 查看次数: |
668 次 |
| 最近记录: |