AILapTrinh.comAI Lập Trình
Gỡ lỗi cùng AI

Ứng dụng chạy chậm: đo trước bằng profiler rồi mới nhờ AI tối ưu đúng chỗ

Gỡ lỗi hiệu năng cùng AI: đo thời gian từng phần, đọc kết quả profiler, truy vấn N+1, thiếu chỉ mục, vòng lặp thừa và cách kiểm lại sau khi sửa.

Small product team in a Can Tho office gathered around a laptop with a blank screen, stopwatch on the desk, afternoon light through blinds, people seen from behind

Với một ứng dụng chạy chậm, câu hỏi đầu tiên không phải là sửa thế nào mà là chậm ở đâu, và câu trả lời phải đến từ việc đo, không đến từ đoán. Người có kinh nghiệm vẫn thường đoán sai chỗ chậm, AI cũng vậy, vì nó không thấy dữ liệu thật và tải thật của bạn.

Nếu dán một hàm cho AI và hỏi “tối ưu giúp”, bạn sẽ nhận về một phiên bản viết lại trông gọn hơn, có khi nhanh hơn vài phần trăm ở chỗ chẳng quan trọng, trong khi chín phần mười thời gian vẫn nằm ở một truy vấn cơ sở dữ liệu ở tệp khác. Bài này đi theo thứ tự đúng: đo, khoanh chỗ chậm, hiểu vì sao chậm, rồi mới nhờ AI đề xuất cách sửa và đo lại.

Đo từ ngoài vào trong

Bắt đầu từ thứ người dùng thấy: trang mất bao lâu để hiện, nút bấm mất bao lâu để phản hồi. Công cụ nhà phát triển của trình duyệt, ở thẻ mạng, cho biết thời gian chờ máy chủ trả lời tách riêng với thời gian tải tệp và thời gian trình duyệt dựng trang. Nếu phần chờ máy chủ chỉ chiếm một phần nhỏ, vấn đề nằm ở phía trình duyệt: tệp quá lớn, ảnh chưa nén, mã JavaScript chạy nặng. Tối ưu mã máy chủ lúc này chẳng giúp được gì.

Nếu phần chờ máy chủ lớn, đi tiếp vào trong. Ghi thời gian ở đầu và cuối xử lý một yêu cầu, rồi chia nhỏ: bao nhiêu cho truy vấn cơ sở dữ liệu, bao nhiêu cho gọi dịch vụ ngoài, bao nhiêu cho tính toán. Nhiều khung làm việc có thanh công cụ gỡ lỗi hiển thị sẵn số truy vấn và thời gian của từng truy vấn trên môi trường phát triển, rất đáng bật.

Đo nhiều lần chứ không phải một lần. Lần chạy đầu thường chậm hơn vì bộ nhớ đệm còn trống, lần sau nhanh hơn. Ghi lại con số của vài lần chạy để có mốc so sánh. Không có mốc thì sau khi sửa bạn sẽ không biết mình đã cải thiện thật hay chỉ cảm thấy vậy.

Công cụ đo theo từng ngôn ngữ

Mỗi ngôn ngữ có công cụ đo riêng, gọi là profiler, ghi lại hàm nào được gọi bao nhiêu lần và tốn bao nhiêu thời gian. Bảng dưới nêu lựa chọn phổ biến, cách bật cụ thể nên kiểm theo tài liệu phiên bản hiện hành.

Ngôn ngữCông cụ đo phổ biếnGhi chú
PythonMô-đun cProfile có sẵn, chạy dạng python -m cProfile -s cumtime kèm tên tệpSắp theo thời gian cộng dồn để thấy hàm nào kéo theo nhiều thời gian nhất
JavaScript trên trình duyệtThẻ hiệu năng trong công cụ nhà phát triểnGhi một lần thao tác chậm, xem các tác vụ dài chặn giao diện
Node.jsCờ --inspect để nối với công cụ nhà phát triển, hoặc cờ --profGhi hồ sơ CPU trong lúc tái hiện thao tác chậm
PHPPhần mở rộng gỡ lỗi có chế độ đo hiệu năng, hoặc công cụ đo chuyên dụngChỉ bật trên máy thử, vì chế độ đo làm chậm thêm đáng kể
SQLLệnh EXPLAIN đặt trước câu truy vấnCho biết truy vấn có dùng chỉ mục hay phải quét cả bảng

Kết quả profiler thường dài và khó đọc lần đầu. Đây là chỗ AI giúp rất tốt: dán hai ba chục dòng đầu của kết quả đã sắp theo thời gian cộng dồn, hỏi nó giải thích hàm nào chiếm thời gian và vì sao có thể như vậy.

Bốn thủ phạm quen mặt

Truy vấn N+1. Lấy danh sách 100 đơn hàng bằng một truy vấn, rồi trong vòng lặp lấy thông tin khách của từng đơn bằng 100 truy vấn nữa. Mỗi truy vấn nhanh, nhưng cộng lại thành chậm, và càng nhiều dữ liệu càng chậm. Thanh công cụ gỡ lỗi đếm được số truy vấn sẽ lộ ra ngay. Cách sửa thường là lấy kèm dữ liệu liên quan trong một truy vấn, mỗi khung làm việc có cách gọi riêng.

Thiếu chỉ mục. Truy vấn lọc theo một cột không có chỉ mục phải quét toàn bộ bảng. Bảng nghìn dòng thì không sao, bảng vài triệu dòng thì chậm hẳn. EXPLAIN sẽ cho thấy truy vấn đang quét cả bảng. Thêm chỉ mục giúp đọc nhanh nhưng làm ghi chậm đi một chút, nên chỉ thêm cho những cột thật sự hay dùng để lọc hoặc sắp xếp.

Vòng lặp lồng nhau trên dữ liệu lớn. Tìm một phần tử trong danh sách bằng vòng lặp, đặt trong một vòng lặp khác, thời gian tăng theo bình phương số phần tử. Đổi danh sách tìm kiếm thành từ điển hoặc tập hợp thường giải quyết ngay.

Gọi dịch vụ ngoài tuần tự. Gọi năm dịch vụ lần lượt, mỗi cái chờ một giây, là năm giây. Nếu chúng không phụ thuộc nhau, gọi song song hoặc lưu đệm kết quả ít thay đổi giảm đáng kể thời gian chờ.

Câu lệnh mẫu khi nhờ AI về hiệu năng

Đưa cho AI số liệu đo được kèm đoạn mã, không chỉ đoạn mã. Các câu dưới giả định bạn đã có kết quả đo.

  • “Kết quả cProfile dưới đây đo một lần xuất báo cáo mất khoảng tám giây. Giải thích ba hàm chiếm nhiều thời gian nhất và lý do có thể, chưa viết lại mã.”
  • “Trang danh sách đơn chạy 101 truy vấn cho 100 đơn. Đây là đoạn mã của bộ điều khiển và mô hình. Chỉ ra chỗ gây truy vấn N+1 và cách lấy kèm dữ liệu theo đúng khung làm việc đang dùng, ghi rõ phiên bản.”
  • “Đây là kết quả EXPLAIN của truy vấn chậm và cấu trúc bảng. Truy vấn có dùng chỉ mục không. Nếu đề xuất chỉ mục mới, nói rõ cái giá phải trả khi ghi dữ liệu.”
  • “Viết lại hàm này cho nhanh hơn nhưng giữ nguyên kết quả. Kèm một ca kiểm thử so kết quả của bản cũ và bản mới trên cùng dữ liệu mẫu.”
  • “Đoạn mã JavaScript này làm giao diện khựng khi gõ vào ô tìm kiếm. Giải thích vì sao và đề xuất cách giảm số lần xử lý, ví dụ chờ người dùng ngừng gõ một khoảng ngắn mới tìm.”

Câu thứ tư quan trọng hơn vẻ ngoài của nó. Tối ưu hiệu năng là nơi AI dễ viết ra bản nhanh hơn mà sai ở ca biên: bỏ mất phần tử trùng, đổi thứ tự sắp xếp, xử lý sai giá trị rỗng. Ca kiểm thử so hai bản trên cùng dữ liệu bắt được những sai lệch đó.

Sửa xong phải đo lại

Mỗi thay đổi hiệu năng cần được chứng minh bằng con số, theo cùng cách đo đã dùng lúc đầu. Quy trình dưới giúp tránh hai cái bẫy: tưởng đã nhanh hơn mà không phải, và nhanh hơn nhưng sai kết quả.

  1. Ghi con số mốc trước khi sửa: thời gian của vài lần chạy, số truy vấn, bộ nhớ dùng, trên cùng dữ liệu mẫu.
  2. Sửa một chỗ duy nhất, chạy lại kiểm thử để chắc kết quả không đổi.
  3. Đo lại theo đúng cách cũ, so với mốc. Nếu không cải thiện rõ, hoàn tác thay đổi đó dù mã mới trông gọn hơn.
  4. Lặp với chỗ chậm tiếp theo trong kết quả profiler, cho tới khi đạt mức chấp nhận được với người dùng.
  5. Thử với dữ liệu lớn hơn thực tế hiện tại vài lần để biết ứng dụng sẽ chịu được tới đâu.
  6. Ghi lại trong mô tả commit: chỗ chậm là gì, đã sửa thế nào, con số trước và sau.

Sửa từng chỗ một có vẻ chậm, nhưng nếu sửa năm chỗ cùng lúc rồi đo, bạn không biết chỗ nào có tác dụng, chỗ nào chỉ thêm độ phức tạp, và chỗ nào âm thầm làm sai kết quả.

Những lời khuyên tối ưu nên nghi ngờ

AI đôi khi đề xuất tối ưu vi mô: đổi cách nối chuỗi, đổi kiểu vòng lặp, lưu độ dài danh sách vào biến. Trong ngôn ngữ hiện đại, những thay đổi này thường không tạo khác biệt đo được với ứng dụng web thông thường, mà lại làm mã khó đọc hơn. Nếu chỗ đó không nằm trong top đầu của kết quả profiler, bỏ qua.

Một loại đề xuất khác cần thận trọng là thêm bộ nhớ đệm ở khắp nơi. Bộ nhớ đệm giúp nhanh hơn thật, nhưng kéo theo câu hỏi khó: khi dữ liệu thay đổi thì xoá đệm lúc nào. Lưu đệm sai là nguồn của những lỗi kiểu khách đã đổi địa chỉ mà trang vẫn hiện địa chỉ cũ. Chỉ lưu đệm khi đã biết chắc chỗ chậm và đã nghĩ rõ cách làm mới dữ liệu.

Cuối cùng, cẩn thận với đề xuất nâng cấp máy chủ để giải quyết chậm. Đôi khi đó là đáp án đúng, nhưng một truy vấn N+1 hay thiếu chỉ mục sẽ vẫn chậm trên máy mạnh gấp đôi, chỉ chậm muộn hơn một chút khi dữ liệu lớn thêm. Sửa nguyên nhân trước, bàn chuyện phần cứng sau.

Khi chậm nằm ở phía trình duyệt

Nhiều trang web chậm mà máy chủ trả lời rất nhanh. Thẻ mạng của công cụ nhà phát triển cho thấy thời gian chờ máy chủ chỉ vài trăm mili giây, phần còn lại là tải ảnh lớn, tải nhiều tệp JavaScript, hoặc trình duyệt bận chạy mã sau khi tải xong. Trên điện thoại tầm trung, phần chạy mã này nặng hơn nhiều so với máy tính của lập trình viên, nên trang thấy nhanh ở văn phòng lại chậm ở tay khách.

Công cụ nhà phát triển có chế độ giả lập điện thoại yếu và mạng chậm, nên bật khi đo để thấy đúng trải nghiệm của số đông người dùng. Thẻ hiệu năng ghi lại các tác vụ dài chặn giao diện, kèm tên hàm gây ra. Với kết quả đó, bạn có thể hỏi AI cụ thể: hàm này chạy hơn nửa giây mỗi lần cuộn trang, vì sao, và có cách nào chỉ xử lý phần đang hiện trên màn hình không.

Những việc thường mang lại khác biệt lớn ở phía trình duyệt khá quen thuộc: nén và đổi kích cỡ ảnh cho đúng khung hiển thị, chỉ tải ảnh khi người dùng cuộn tới, tách mã JavaScript để trang đầu không phải tải những phần chưa cần. Hỏi AI về những việc này hợp lý, nhưng vẫn đo trước và đo sau theo cùng điều kiện giả lập.

Câu hỏi thường gặp

Có nên nhờ AI tối ưu cả tệp mã cho nhanh không?

Không nên. Không có số liệu đo, AI sẽ tối ưu chỗ trông có vẻ chậm chứ không phải chỗ chậm thật, và viết lại nhiều mã làm tăng rủi ro sai. Đo bằng profiler trước, chỉ đưa cho AI đúng phần chiếm nhiều thời gian nhất.

Truy vấn N+1 là gì, nhận ra thế nào?

Là khi lấy một danh sách bằng một truy vấn rồi lấy dữ liệu liên quan của từng phần tử bằng một truy vấn riêng, tổng cộng N+1 truy vấn. Nhận ra bằng cách đếm số truy vấn trên một trang: số truy vấn tăng theo số dòng hiển thị là dấu hiệu rõ.

Thêm chỉ mục cho mọi cột có làm cơ sở dữ liệu nhanh hơn không?

Không. Mỗi chỉ mục làm thao tác ghi chậm đi và tốn thêm dung lượng. Chỉ thêm cho cột hay dùng để lọc, nối bảng hoặc sắp xếp trong những truy vấn quan trọng, và kiểm bằng EXPLAIN xem truy vấn có thực sự dùng chỉ mục đó.

Profiler có làm sai kết quả đo không?

Có làm chậm thêm, đôi khi đáng kể, nên con số tuyệt đối khi bật profiler không phản ánh tốc độ thật. Dùng nó để so tỉ lệ giữa các hàm. Con số thời gian thật thì đo riêng khi đã tắt profiler.

Ứng dụng chỉ chậm vào giờ cao điểm thì gỡ thế nào?

Đó thường là vấn đề tranh chấp tài nguyên: khoá cơ sở dữ liệu, hết kết nối, hết tiến trình xử lý. Cần nhật ký có thời gian, số yêu cầu đồng thời và chỉ số máy chủ vào đúng lúc chậm. Tái hiện bằng công cụ tạo tải trên máy thử trước khi kết luận.

AI viết lại hàm nhanh hơn, làm sao chắc kết quả vẫn đúng?

Viết ca kiểm thử chạy cả bản cũ và bản mới trên cùng bộ dữ liệu mẫu, gồm ca biên như danh sách rỗng, giá trị trùng, giá trị rỗng, rồi so kết quả. Chỉ thay bản cũ khi mọi ca cho kết quả giống hệt nhau.

Cần tư vấn cụ thể cho trường hợp của bạn?

Chúng tôi sẽ liên hệ trong vòng 24 giờ.

Đăng ký tư vấn ngay

Bài viết liên quan

Bạn cần hỗ trợ thêm?

Để lại thông tin, chúng tôi sẽ liên hệ trong 24 giờ.

hoặc
Gọi ngay 0926 138 138