Các câu trả lời khác khá kỹ lưỡng và Closures in Ruby bao quát rộng rãi các khác biệt chức năng.Tôi đã tò mò về phương pháp nào sẽ thực hiện tốt nhất cho các phương pháp mà tùy chọn chấp nhận một khối, vì vậy tôi đã viết một số tiêu chuẩn (sẽ tắt this Paul Mucur post). Tôi so sánh ba phương pháp:
- & khối trong phương pháp chữ ký
- Sử dụng
&Proc.new
- Bao bì
yield
trong một khối
Đây là mã:
require "benchmark"
def always_yield
yield
end
def sometimes_block(flag, &block)
if flag && block
always_yield &block
end
end
def sometimes_proc_new(flag)
if flag && block_given?
always_yield &Proc.new
end
end
def sometimes_yield(flag)
if flag && block_given?
always_yield { yield }
end
end
a = b = c = 0
n = 1_000_000
Benchmark.bmbm do |x|
x.report("no &block") do
n.times do
sometimes_block(false) { "won't get used" }
end
end
x.report("no Proc.new") do
n.times do
sometimes_proc_new(false) { "won't get used" }
end
end
x.report("no yield") do
n.times do
sometimes_yield(false) { "won't get used" }
end
end
x.report("&block") do
n.times do
sometimes_block(true) { a += 1 }
end
end
x.report("Proc.new") do
n.times do
sometimes_proc_new(true) { b += 1 }
end
end
x.report("yield") do
n.times do
sometimes_yield(true) { c += 1 }
end
end
end
Hiệu suất tương tự giữa Ruby 2.0.0p247 và 1.9.3p392. Dưới đây là các kết quả cho 1.9.3:
user system total real
no &block 0.580000 0.030000 0.610000 ( 0.609523)
no Proc.new 0.080000 0.000000 0.080000 ( 0.076817)
no yield 0.070000 0.000000 0.070000 ( 0.077191)
&block 0.660000 0.030000 0.690000 ( 0.689446)
Proc.new 0.820000 0.030000 0.850000 ( 0.849887)
yield 0.250000 0.000000 0.250000 ( 0.249116)
Thêm một rõ ràng &block
param khi nó không phải lúc nào cũng sử dụng thực sự làm chậm phương pháp. Nếu khối là tùy chọn, không thêm nó vào chữ ký phương thức. Và, để truyền các khối xung quanh, gói yield
trong khối khác là nhanh nhất.
Điều đó nói rằng, đây là kết quả cho một triệu lần lặp lại, do đó, đừng lo lắng về nó quá nhiều. Nếu một phương pháp làm cho mã của bạn rõ ràng hơn với chi phí bằng một phần triệu giây, hãy sử dụng nó.
Lưu ý phụ: 'def thrice (& block)' là tự ghi nhiều tài liệu hơn, đặc biệt là so với 'yield' được chôn ở đâu đó trong một phương thức lớn. –