記得有一次想要測試一下自己 2 種 function 寫法的效能,但當時的我連關鍵字都不知道要下什麼於是作罷,直到後來偶然看到這篇文章:Bcrypt vs BcryptJS Benchmark with Node.js,才意外發現可以用 console.time 這個語法來測試 function 的效能,以下簡單介紹一下用法。
Table of Contents
1. console.time() 用法
根據 MDN 的 document ,console.time 會和 console.timeEnd 一起使用,瀏覽器或 node.js 會在執行 console.time 的時候開始一個時間戳記,這個時間戳記會計算到執行 console.timeEnd 所花費的時間,因此只需要把要執行的程式用 console.time 和 console.timeEnd 就可以知道執行該程式花費了多少時間。
console.time 和 console.timeEnd 都可以傳一個 label 參數,瀏覽器或 node.js 會計算一樣 label 的 console.time 和 console.timeEnd 之間的程式執行花費了多少時間,如下:
console.time();
Math.pow(2, 10);
// 計算 2 的 10 次方
console.timeEnd();
// 若 console.time 和 console.timeEnd 沒有給參數,則會用 'default' 來表示時間戳記
// default: 0.005ms
console.time('2 的 10 次方花費的時間');
Math.pow(2, 10);
console.timeEnd('2 的 10 次方花費的時間');
// 若 console.time 和 console.timeEnd 有給參數,則用該參數來表示時間戳記
// 2 的 10 次方花費的時間: 0.004ms
2. 用 console.time 來測試費氏數列的各種解法
首先參考這篇【 JavaScript 】JavaScript 費氏數列的 3 種解法,接著用 console.time 來測試 3 種解法的效能吧!
2.1 宣告不同方法的 function
先宣告 3 種解法的 function:
const fibRecursive = (num) => {
if (num < 2) return num;
return fibRecursive(num - 1) + fibRecursive(num - 2);
};
const fibForMethod = (num) => {
if (num < 2) return num;
const arr = [0, 1];
for (let i = 2; i <= num; i++) {
arr[i] = arr[i - 1] + arr[i - 2];
}
return arr[num];
};
const fibMemoization = (num) => {
if (!fibMemoization.cache) {
fibMemoization.cache = {};
}
if (fibMemoization.cache[num] !== undefined) {
return fibMemoization.cache[num];
}
fibMemoization.cache[0] = 0;
fibMemoization.cache[1] = 1;
fibMemoization.cache[num] = fibMemoization(num - 1) + fibMemoization(num - 2);
return fibMemoization.cache[num];
};
2.2 宣告效能測試的 function
通常一個 function 只執行一次來測試效能的誤差會比較大,因此可以寫一個 function 來決定要重複執行幾次要測試的 function:
const fibPerfTest = (functionExecutionTimes, num) => {
for (let i = 0; i < functionExecutionTimes; i++) {
fibRecursive(num);
}
for (let i = 0; i < functionExecutionTimes; i++) {
fibForMethod(num);
}
for (let i = 0; i < functionExecutionTimes; i++) {
fibMemoization(num);
}
};
如此一來就可以決定要重複執行幾次 function 還有費氏數列要計算到第幾個項目來測試效能。
2.3 加上 console.time 和 console.timeEnd
最後加上 console.time 和 console.timeEnd 就可以知道重複執行 function 所要花費的時間:
const fibPerfTest = (functionExecutionTimes, num) => {
console.time("Recursive method");
for (let i = 0; i < functionExecutionTimes; i++) {
fibRecursive(num);
}
console.timeEnd("Recursive method");
console.time("For loop method");
for (let i = 0; i < functionExecutionTimes; i++) {
fibForMethod(num);
}
console.timeEnd("For loop method");
console.time("Memoization method");
for (let i = 0; i < functionExecutionTimes; i++) {
fibMemoization(num);
}
console.timeEnd("Memoization method");
};
2.4 JavaScript 效能測試
fibPerfTest(10, 40);
// 計算出費氏數列的第 40 項並執行 10 次,三種方法花費的時間如下
// Recursive method: 11.708s
// For loop method: 0.162ms
// Memoization method: 0.08ms
不意外的:遞迴解花費的時間最多,效能最好的則是 memoization 方法。
3. 結論
雖然有一些套件:Benchmark.js 或是網頁:JSBench.me 可以測試程式效能,但有時候在測試後端的 function 的時候,可能有資安或是資料庫的問題,還是需要自己寫一些 code 在 local 測,意外發現 console.time 這個神奇的東西,讓我終於不用再一直 new date 了,內牛滿面嗚嗚,希望這篇文章有幫助到想在 JavaSciprt 中做效能測試的人~
如果覺得我的文章有幫助的話,歡迎幫我的粉專按讚哦~謝謝你!