Đo lường hiệu suất giúp bạn đo lường cách ứng dụng của bạn hoạt động. Không chỉ về tốc độ - còn có những yếu tố quan trọng khác nữa. Hãy cùng xem những gì cần đo lường và cách thực hiện:

Tốc độ

  • Sử dụng bộ đếm thời gian (timer) để theo dõi thời gian chạy của các phần khác nhau trong ứng dụng của bạn
  • So sánh những thời gian này khi bạn thực hiện thay đổi để xem liệu có nhanh hơn không

Ruby có một module Benchmark tích hợp sẵn:

require 'benchmark'

time = Benchmark.measure do
  # Mã của bạn ở đây
end

puts "Thời gian thực thi: #{time.real} giây"

Sử dụng bộ nhớ

  • Kiểm tra xem ứng dụng của bạn sử dụng bao nhiêu RAM
  • Tìm kiếm rò rỉ bộ nhớ (khi ứng dụng của bạn không giải phóng bộ nhớ mà nó không còn cần nữa)
  • Các công cụ như Task Manager (Windows) hoặc Activity Monitor (Mac) có thể giúp đỡ

Để phân tích bộ nhớ trong Ruby, bạn có thể sử dụng gem memory_profiler https://github.com/SamSaffron/memory_profiler:

gem install memory_profiler

require 'memory_profiler'

report = MemoryProfiler.report do
  # Mã của bạn ở đây
end

report.pretty_print

Thu gom rác

Ruby's Garbage Collection tự động giải phóng bộ nhớ bằng cách loại bỏ các đối tượng không còn sử dụng. Nó sử dụng thuật toán đánh dấu và quét (mark-and-sweep) để xác định và xóa các đối tượng không được tham chiếu, giúp quản lý bộ nhớ hiệu quả mà không cần can thiệp thủ công từ các nhà phát triển.

GC::Profiler.enable
# Mã của bạn ở đây
GC::Profiler.report
GC::Profiler.disable

Hiệu suất mạng

  • Đo lường lượng dữ liệu mà ứng dụng của bạn gửi và nhận
  • Thời gian thực hiện các thao tác mạng
  • Sử dụng các công cụ phát triển tích hợp (built-in) trong trình duyệt web cho các ứng dụng web

Bạn có thể sử dụng thư viện net/http và đo lường nó:

require 'benchmark'
require 'net/http'

time = Benchmark.measure do
  response = Net::HTTP.get_response(URI('https://example.com'))
  puts "Dữ liệu nhận được: #{response.body.length} bytes"
end

puts "Thời gian phản hồi: #{time.real} giây"

Đối với các cuộc gọi API hoặc yêu cầu dịch vụ bên ngoài, sử dụng gem httplog https://github.com/trusche/httplog. Nó sẽ ghi lại tất cả các yêu cầu HTTP được thực hiện bởi ứng dụng của bạn.

Đầu vào/ra ổ cứng - Disk Input/Output (I/O)

  • Theo dõi tốc độ mà ứng dụng của bạn đọc và ghi vào ổ cứng
  • Đếm số lần ứng dụng của bạn truy cập vào đĩa
  • Nhiều ngôn ngữ lập trình có thư viện để giúp đo lường điều này

Dưới đây là một ví dụ về đo lường hiệu suất đọc tệp:

require 'benchmark'

time = Benchmark.measure do
  content = File.read('large_file.txt')
  puts "Kích thước tệp: #{content.length} bytes"
end

puts "Thời gian đọc: #{time.real} giây"

Sử dụng CPU

  • Giám sát mức độ sử dụng công suất xử lý của máy tính mà ứng dụng của bạn sử dụng
  • Mức sử dụng CPU cao có thể làm chậm toàn bộ hệ thống

Bạn có thể sử dụng gem sys-cpu https://github.com/djberg96/sys-cpu:

gem install sys-cpu

require 'sys/cpu'

before = Sys::CPU.load_avg[0]
# Mã của bạn ở đây
after = Sys::CPU.load_avg[0]

puts "Thay đổi mức sử dụng CPU: #{after - before}"

Đo lường yêu cầu

Sử dụng Apache Bench (ab) https://httpd.apache.org/docs/2.4/programs/ab.html hoặc wrk https://github.com/wg/wrk để kiểm tra tải. Ví dụ:
ab -n 1000 -c 10 http://localhost:3000/
Điều này gửi 1000 yêu cầu với 10 người dùng đồng thời.

Các gem khác

status_page

Nếu bạn đang sử dụng Sidekiq, nó cung cấp các phân tích tích hợp sẵn. Đối với các bộ xử lý công việc khác, hãy cân nhắc sử dụng gem status_page https://github.com/rails-engine/status-page. Các dịch vụ hiện được hỗ trợ:

  • DB
  • Cache
  • Redis
  • Sidekiq
  • Resque

stackprof

Chúng ta sử dụng stackprof https://rubygems.org/gems/stackprof để xác định các điểm nghẽn hiệu suất trong mã Ruby. Nó phân tích ứng dụng, cho thấy các phương thức nào tiêu tốn nhiều thời gian CPU hoặc bộ nhớ nhất. Điều này giúp xác định các phần mã chậm để tối ưu hóa, cải thiện hiệu suất ứng dụng tổng thể.

Mẹo để đo lường hiệu suất

  • Kiểm tra ứng dụng của bạn trong điều kiện bình thường và tải nặng (Duy trì tốc độ cho trang web của bạn: Các mẹo tối ưu hóa thiết yếu cho website có lưu lượng truy cập cao https://vulehuan.com/vi/blog/2024/7/duy-tri-toc-do-cho-trang-web-cua-ban-cac-meo-toi-uu-hoa-thiet-yeu-cho-website-co-luu-luong-truy-cap-cao-668919cff0915ca45912b8e6.html)
  • So sánh kết quả của bạn với các phiên bản trước của ứng dụng
  • Sử dụng các công cụ đo lường chuyên biệt để có phân tích chi tiết hơn
  • Để đo lường toàn diện: Bạn có thể sử dụng gem benchmark-ips https://github.com/evanphx/benchmark-ips để có các điểm đo lường chi tiết hơn. Nó tự động xác định các điểm dữ liệu để kiểm tra mã của chúng ta, vì vậy chúng ta có thể tập trung vào kết quả thay vì đoán số lần lặp lại như với thư viện Benchmark truyền thống.
  • Hiệu suất ứng dụng tổng thể: Sử dụng gem rack-mini-profiler https://github.com/MiniProfiler/rack-mini-profiler. Nó sẽ thêm huy hiệu tốc độ vào các trang của bạn và cung cấp thông tin chi tiết về các truy vấn SQL, thời gian render view và nhiều hơn nữa.
  • Hiệu suất truy vấn SQL: Rails có ghi log truy vấn tích hợp sẵn. Trong quá trình phát triển, bạn sẽ thấy thời gian truy vấn trong log máy chủ của mình. Để có phân tích chi tiết hơn, sử dụng gem bullet https://vulehuan.com/en/blog/2024/6/stop-website-slowdowns-identify-fix-n1-queries-with-gem-bullet-667a5f57d57f3511fdf8e376.html để xác định các truy vấn N+1.
  • ruby-prof https://ruby-prof.github.io/ hữu ích nếu chương trình của bạn chậm và bạn không biết tại sao. Nó có thể giúp bạn theo dõi các phương thức chậm, phân bổ nhiều đối tượng hoặc phân bổ đối tượng có mức sử dụng bộ nhớ cao. Thường thì kết quả sẽ khiến bạn ngạc nhiên - khi phân tích những gì bạn nghĩ bạn biết hầu như luôn luôn sai.

Nhớ chỉ sử dụng các công cụ này trong môi trường development hoặc staging, vì chúng có thể ảnh hưởng đến hiệu suất trong production.

Để có cách tiếp cận toàn diện, bạn có thể tạo một môi trường đo lường chuyên dụng tương tự như production của bạn, và chạy các công cụ này ở đó để có được kết quả chính xác nhất.