JavaScript 效能

【 JavaScript 】JavaScript 效能測試的好幫手 ⏤ console.time

記得有一次想要測試一下自己 2 種 function 寫法的效能,但當時的我連關鍵字都不知道要下什麼於是作罷,直到後來偶然看到這篇文章:Bcrypt vs BcryptJS Benchmark with Node.js,才意外發現可以用 console.time 這個語法來測試 function 的效能,以下簡單介紹一下用法。

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 中做效能測試的人~

如果覺得我的文章有幫助的話,歡迎幫我的粉專按讚哦~謝謝你!

Leave a Comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

回到頂端