Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

So sánh hiệu năng: Exception vs Break và Return trong Ruby

Tôi luôn nghi ngờ exception chậm hơn flow control mechanism khác trong Ruby.畢竟, exception phức tạp hơn hẳn "break" hoặc "return" đơn giản. Nhưng tôi từng sai hunches, nên test thử.

Code dưới dùng `benchmark-ips` so sánh relative performance thoát loop qua exception, break, return. Đã thấy ví dụ benchmark này MRI 1.9. Muốn thử 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ả khá staggering. Function dùng exception kém hơn half so với break và return.


$ 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 benchmark hoàn hảo

Có vài issue chưa biết compensate. Ví dụ, exception và break method phải return. Vì vậy làm nhiều hơn method chỉ return. Cũng tò mò rescue exception có thêm overhead không. Nhưng không rescue làm benchmark abort.

Vẫn, exception chậm hơn hẳn các ví dụ khác, tôi nghĩ kết quả có ý nghĩa dù không hoàn hảo.

Bài học rút ra?

Nếu dùng exception làm flow control mechanism. Dừng ngay! Đặc biệt nếu loop raise và catch exception lặp lại.

Sẽ thay đổi cách tôi dùng exception? Có lẽ không. Tôi chịu đựng chút chậm nếu chậm là exception to the rule. :)

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

Josh Cheek (@josh_cheek) viết version benchmark toàn diện hơn. Chạy trên multiple Ruby implementation. Xem kết quả tại đây. Hình như break vẫn thắng. :)