Trong quá trình phát triển hoặc vận hành hệ thống phần mềm, có những lúc phát sinh ra nhiều vấn đề mà chúng ta không lường trước được. Một khi ứng dụng được tung ra thị trường, lượng người dùng tăng theo từng ngày tạo ra sự đa dạng về hành vi lẫn dữ liệu sinh ra trong hệ thống. Chúng kết hợp với nhau để bùng nổ những lỗi mà quá trình kiểm thử trước đó không hề biết.
Một trong số đó có thể kể đến 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, có vẻ bạn phát hiện ra hoặc nghi ngờ một hàm nào đó mất thời gian xử lý. Để cho chắc chắn thì tất nhiên phải làm cách nào đó để đo xem hàm đó tốn bao nhiêu thời gian xử lý. Có nhiều cách để tìm xem hàm nào đang tiêu tốn thời gian. Nhiều ứng dụng APM có khả năng kiểm soát và chuẩn đoán hiệu suất ứng dụng rất tốt, kịp thời cảnh báo vấn đề đến người quản trị. Một vài dịch vụ APM còn 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 để xử lý. Hay chí ít là cảnh báo thời gian phản hồi quá lâu. Nhưng đổi lại giá thành của chúng không hề rẻ, nếu có miễn phí thì nhiều hạn chế kèm theo buộc phải nâng cấp nếu muốn dùng thoải mái. 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í, ai cũng có thể tiếp cận được.
Date.now()
, console.time()
, performance.now()
, process.hrtime()
... là các hàm thường được dùng để đo khoảng thời gian thực hiện lệnh. Về cơ bản, chỉ cần kẹp giữa hàm cần đo thì sẽ tính được thời gian thực thi.
Ví dụ dùng Date
để tính thời gian thực thi của hàm functionToBeMeasured
giống như sau:
const start = Date.now();
await functionToBeMeasured();
const end = Date.now();
console.log(`Execution time: ${end - start} ms`);
Cũng có thể làm tương tự với console.time
:
console.time('executionFunctionToBeMeasured');
await functionToBeMeasured();
console.timeEnd('executionFunctionToBeMeasured');
Tuy vậy, 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()
trong trình duyệt 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 nguyên lý đo thời gian, vấn đề là làm cách nào để dùng. Chẳng lẽ cứ phải tìm và kẹp giữa hàm bằng 2 dòng start
và end
? Tin vui là không cần phải làm thế. Ý tưởng lúc này là viết một hàm gói gọn hàm khác để đo thời gian. Hàm này có đầu vào là một hàm cần đo thời gian, đầu ra là kết quả của hàm đó kèm với thời gian thực thi. Một cái gì đó trông giống như dưới đây:
calcExecuteTime(functionToBeMeasured);
Với calcExecuteTime
làm hàm cần tạo ra. functionToBeMeasured
là hàm cần do thời gian. Đôi khi functionToBeMeasured
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ố ngữ cảnh để nhận this
từ nơi gọi hàm, đảm bảo ngữ cảnh cho hàm.
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...));
Tổng hợp lại, 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ó thể sửa lại hàm tuỳ thích, ví dụ thay vì console.log
thì ghi lại thời gian thực hiện hàm vào đâu đó, ví dụ như một tệp .log
hoặc bắn lên dịch vụ đám mây nào đó. Ngoài ra có thể thêm một cờ bật/tắt tính năng tính năng đo thời gian khi nó không cần thiết nữa.
Tham khảo:
Bí mật ngăn xếp của Blog
Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!
Đăng ký nhận thông báo bài viết mới
Bình luận (1)