Đo lường thời gian thực hiện hàm trong Javascript một cách thanh lịch

Đo lường thời gian thực hiện hàm trong Javascript một cách thanh lịch

Tin ngắn hàng ngày dành cho bạn
  • Thêm một bài viết nữa hướng dẫn rất dễ hiểu về jj nè mọi người ơi 🤓

    Jujutsu For Busy Devs

    » Xem thêm
  • MCP còn khá mới cho nên nó đang là mục tiêu để hacker khai thác. Mới đây một nhóm nghiên cứu đã khai thác lỗ hổng từ MCP của Supabase để đọc được toàn bộ cấu trúc cơ sở dữ liệu Supabase MCP can leak your entire SQL database. Vừa rồi họ lại tiếp tục khai thác Claude Jailbroken to Mint Unlimited Stripe Coupons.

    Về cơ bản kiểu tấn công này là trò chuyện để máy chủ làm theo yêu cầu. Vừa dễ mà lại vừa khó. Nếu bạn đang phát triển MCP thì cũng nên lưu ý xác thực dữ liệu đầu vào của người dùng nhé. Đừng bao giờ tin vào bất cứ điều gì người dùng nhập 😅

    » Xem thêm
  • Hôm qua mới nhắc đến MinIO thì hôm nay đã thấy RustFS cũng làm được tương tự, nhưng viết bằng... Rust 😆

    À RustFS vẫn đang trong giai đoạn hoàn thiện gấp rút nên vài nữa thôi chắc sẽ có nhiều người so sánh hiệu năng của 2 thằng này đây 🤓

    » Xem thêm

Vấn đề

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.

Đ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 đượ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 startend? 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:

Cao cấp
Hello

Tôi & khao khát "chơi chữ"

Bạn đã thử viết? Và rồi thất bại hoặc chưa ưng ý? Tại 2coffee.dev chúng tôi đã có quãng thời gian chật vật với công việc viết. Đừng nản chí, vì giờ đây chúng tôi đã có cách giúp bạn. Hãy bấm vào để trở thành hội viên ngay!

Bạn đã thử viết? Và rồi thất bại hoặc chưa ưng ý? Tại 2coffee.dev chúng tôi đã có quãng thời gian chật vật với công việc viết. Đừng nản chí, vì giờ đây chúng tôi đã có cách giúp bạn. Hãy bấm vào để trở thành hội viên ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.

Bình luận (1)

Nội dung bình luận...
Avatar
Tuan Nguyen2 năm trước

Thử chạy cái hàm đó trong 1_000_000 rồi tính trung bình sau đó đem so với chạy cái hàm đó 1 lần. Kết quả sẽ bất ngờ đó. Đó là cơ chế của node

Trả lời
Avatar
Xuân Hoài Tống2 năm trước

Bạn ơi đó là cơ chế gì vậy ạ?