Đo lường thời gian thực hiện hàm trong Javascript một cách thanh lịch
Bài viết được sự cho phép bởi tác giả Sơn Dương
Vấn đề
Trong quá trình phát triển ứng dụng hoặc đang vận hành nó trong môi trường production sẽ có lúc phát sinh ra nhiều vấn đề mà chúng ta không lường trước được. Khi ứng dụng được tung ra thị trường, chắc chắn lượng người dùng sẽ nhiều lên từng ngày, từ đó tạo ra sự đa dạng về hành vi lẫn dữ liệu người dùng thu thập được. Chúng kết hợp với nhau tạo ra nhiều trường hợp phát sinh lỗi mà quá trình kiểm thử trước đó không hề phát hiện ra.
Một trong số đó có thể kể đến như là tốc độ phản hồi API bỗng trở nên chậm chạp mặc dù lượng người sử dụng là không nhiều. Khi kiểm tra lại tính năng gây ra tình trạng đó, có vẻ bạn phát hiện ra hoặc đang nghi ngờ một hàm nào đó chiếm lượng thời gian xử lý lớn. Để chắc chắn là mình đúng thì tất nhiên phải đo được xem cụ thể là hàm đó tốn bao nhiêu thời gian để xử lý.
Có nhiều cách để biết hàm nào đang gây chậm hệ thống. Các ứng dụng APM với khả năng kiểm soát và chuẩn đoán ứng dụng của bạn rất tốt để kịp thời cảnh báo vấn đề. Một vài dịch vụ APM có tính năng thu thập hoặc cảnh báo theo thời gian thực nếu như chúng phát hiện ra một hàm nào đó đang mất quá nhiều thời gian để thực hiện, hoặc thời gian phản hồi của API là quá lâu. Nhưng đổi lại, giá thành của chúng không hề rẻ, hoặc nếu có miễn phí thì nhiều hạn chế sẽ phát sinh. Vì lẽ đó không phải ai cũng có điều kiện sử dụng APM, đó là lúc bạn cần đến một cách “xôi thịt” hơn nhưng lại hoàn toàn miễn phí mà ai cũng có thể tiếp cận được.
Đo lường thời gian thực hiện hàm trong Javascript
Date.now()
, console.time()
, performance.now()
, process.hrtime()
… là các hàm thường hay được sử dụng để đo khoảng thời gian mà hàm thực hiện. Về cơ bản, chỉ cần kẹp giữa hàm cần đo bằng chúng thì sẽ tính được thời gian thực thi.
Ví dụ sau dử dụng Date
để tính thời gian thực thi bằng cách trừ hai khoảng thời gian trước và sau khi hàm được chạy.
const start = Date.now();
await functionToBeMeasured();
const end = Date.now();
console.log(`Execution time: ${end - start} ms`);
Ngoài ra, đơn giản hơn thì dùng console.time
:
console.time('executionFunctionToBeMeasured');
await functionToBeMeasured();
console.timeEnd('executionFunctionToBeMeasured');
console.time
không mang lại độ chính xác cao. Nếu muốn độ chính xác theo phần nghìn giây, hãy sử dụng hàm mạnh mẽ hơn với performance.now()
hoặc process.hrtime()
nếu sử dụng Node.js.
const start = performance.now();
await functionToBeMeasured();
const end = performance.now();
console.log(`Execution time: ${end - start} ms`);
Sau khi biết cách đo thời gian, một vấn đề khác nảy sinh đó chính là cần phải đặt hàm cần đo kẹp giữa hai hàm tính thời gian. Điều này gây ra sự xáo trộn mã trong dự án của bạn, phải sửa nhiều hơn, mã trở nên cồng kềnh hơn và khó kiểm soát.
Việc làm Javascript lương cao trên TopDev
Ý tưởng lúc này là viết một hàm để gói gọn tính năng đo thời gian thực thi. Đầu vào là một hàm cần tính còn đầu ra là kết quả của hàm đó cùng với thời gian thực thi. Một hàm gì đó trông giống như dưới đây:
calcExecuteTime(functionToBeMeasured);
functionToBeMeasured
đôi khi là hàm có cả tham số, vì thế hãy sửa lại một chút.
calcExecuteTime(() => functionToBeMeasured(arg1, arg2...));
Nếu trong functionToBeMeasured
có sử dụng this
, hãy thêm một tham số context để nhận this
từ nơi gọi.
calcExecuteTime(context, () => functionToBeMeasured(arg1, arg2...));
Cuối cùng, nên thêm một tham số name
để xác định được cuộc gọi hàm từ đâu.
calcExecuteTime(name, context, () => functionToBeMeasured(arg1, arg2...));
Hàm calcExecuteTime
có thể giống như sau:
const calcExecuteTime = async (name, context, fn) => {
const start = process.hrtime();
const result = await fn.call(context);
const stop = process.hrtime(start);
const executeTime = (stop[0] * 1e9 + stop[1]) / 1e9;
console.log(`${name} execution time: ${executeTime}s`);
return result;
};
Bây giờ hãy thử gọi hàm xem:
calcExecuteTime("Execute ToBeMeasured", this, () => functionToBeMeasured(arg1, arg2...));
// Execute ToBeMeasured execution time: 0.000178s
Bạn cũng có thể sửa lại hàm tùy vào mục đích, ví dụ thay vì console.log
thì hãy logging lại thời gian thực hiện hàm vào đâu đó. Hoặc nâng cấp hàm lên ví dụ như thêm một cờ bật/tắt tính năng tính thời gian.
Bài viết gốc được đăng tải tại vntalking.com
Có thể bạn quan tâm:
- Lodash – Tiện ích dắt túi của dân lập trình Javascript
- Một số cách để viết mã dễ đọc hơn trong JavaScript/Node.js
- Bạn biết gì về thuật toán Radix Sort trong JavaScript?
Xem thêm các việc làm IT hấp dẫn tại TopDev
- N Nâng tầm kỹ năng JavaScript: 6 khái niệm không thể bỏ qua
- J Jest là gì? Hướng dẫn thực hiện kiểm thử JavaScript với Jest
- S Strict Mode trong JavaScript – Sử dụng Strict Mode như thế nào cho tốt?
- T Tìm hiểu về Intl.RelativeTimeFormat trong JavaScript
- K Kinh nghiệm xử lý câu lệnh điều kiện trong JavaScript
- C Các cách xóa một property của Object trong Javascript
- K Kinh nghiệm truy xuất giá trị trong object lồng nhau trong Javascript
- H Hằng số và tính bất biến trong JavaScript
- T Thư viện Driver.js tạo hướng dẫn tương tác trang web
- C Các tips hiệu quả nhất khi làm việc với Javascript