Computer >> Máy Tính >  >> Lập trình >> Ruby

Đo điểm chuẩn ngoại lệ trong Ruby - vâng, chúng rất chậm.

Tôi luôn nghi ngờ mạnh mẽ rằng các ngoại lệ sẽ chậm trong ruby ​​so với các cơ chế kiểm soát dòng chảy khác. Xét cho cùng - các trường hợp ngoại lệ phức tạp hơn rất nhiều so với "break" hoặc "return" đơn giản. Nhưng linh cảm của tôi đã sai trước đây, vì vậy tôi nghĩ rằng tôi nên thử nghiệm nó.

Trong đoạn mã bên dưới, tôi đang sử dụng viên ngọc benchmark-ips để so sánh hiệu suất tương đối của việc thoát khỏi một vòng lặp thông qua ngoại lệ, ngắt và trả về. Tôi đã thấy các ví dụ trên web về những người làm các điểm chuẩn như thế này với mri 1.9. Nhưng tôi muốn dùng thử với mri 2.2.

require 'benchmark/ips'

def exit_via_exception
  5.times do 
    raise RuntimeError
  end
rescue
end

def exit_via_break
  5.times do 
    break
  end
end

def exit_via_return
  5.times do 
    return
  end
end

Benchmark.ips do |x|
  x.report("exception") {  exit_via_exception }
  x.report("break") {  exit_via_break }
  x.report("return") {  exit_via_return }
end

Kết quả là khá đáng kinh ngạc. Hàm sử dụng ngoại lệ nhanh hơn một nửa so với hàm sử dụng ngắt và trả lại.

$ ruby exception_benchmark.rb
Calculating -------------------------------------
           exception    50.872k i/100ms
               break   125.322k i/100ms
              return   124.173k i/100ms
-------------------------------------------------
           exception    714.795k (± 2.7%) i/s -      3.612M
               break      3.459M (± 3.1%) i/s -     17.294M
              return      3.379M (± 3.0%) i/s -     16.888M

Đây không phải là điểm chuẩn hoàn hảo

Có một số vấn đề mà tôi không biết phải làm thế nào để bù đắp. Ví dụ, các phương thức ngoại lệ và ngắt phải trả về. Vì vậy, họ đang làm nhiều hơn là phương thức chỉ trả về. Ngoài ra, tôi muốn xem liệu việc giải cứu ngoại lệ có làm tăng chi phí hiệu suất hay không. Nhưng không giải cứu nó sẽ khiến điểm chuẩn bị hủy bỏ.

Tuy nhiên, ngoại lệ chậm hơn nhiều so với các ví dụ khác mà tôi nghĩ rằng kết quả có ý nghĩa ngay cả khi chúng không hoàn hảo.

Bài học chúng ta đã học?

Nếu bạn đang sử dụng ngoại lệ làm cơ chế kiểm soát luồng. Dừng lại ngay! Đặc biệt là nếu bạn có một vòng lặp bao gồm các ngoại lệ được đưa ra và bị bắt lặp đi lặp lại.

Điều này sẽ thay đổi cách cá nhân tôi sử dụng các ngoại lệ? Chắc là không. Tôi có thể sống với một chút chậm chạp nếu sự chậm chạp là một ngoại lệ của quy luật. :)

... Nhưng JRuby và RBx thì sao?

Josh Cheek (@josh_cheek trên twitter) đã viết phiên bản của riêng mình về điểm chuẩn này, phiên bản toàn diện hơn của tôi. Và anh ấy đã chạy nó với nhiều lần triển khai ruby. Bạn có thể xem kết quả của anh ấy ở đây. Rõ ràng break vẫn là người chiến thắng. :)