2013-01-17 36 views
5

Tôi có điều kiện để kiểm tra xem xóa và bài viết nếu người dùng là chủ sở hữu.nếu điều kiện vs &&, có hiệu suất nào đạt được

delete_article if user.owner? 

Một cách khác là

user.owner? && delete_article 

được có bất kỳ lợi ích trong việc lựa chọn một trong hai hay là nó chỉ là một văn phong

+10

trước tiên là rõ ràng hơn về ý định – apneadiving

+0

Viết điểm chuẩn và tự tìm ra. Thật dễ dàng, đủ để làm. –

+0

Các lợi ích về hiệu năng như thế này (nếu có) sẽ không đáng kể đối với một ứng dụng web (độ trễ mạng/IO sẽ làm giảm bất kỳ lợi ích nào). Vì vậy, tôi sẽ nhắm đến phong cách, cá nhân tôi thích 'if' hơn' && 'trong trường hợp này. – Kris

Trả lời

2

Dưới đây là một số mã để kiểm tra tốc độ if so với &&.

require 'benchmark' 

n = 10_000_000 

puts RUBY_VERSION, n 
puts 

Benchmark.bm(2) do |b| 
    10.times do 
    b.report('if') { n.times { true if true } } 
    b.report('&&') { n.times { true && true } } 
    end 
end 

Và kết quả:

1.9.3 
10000000 

     user  system  total  real 
if 0.970000 0.000000 0.970000 ( 0.975714) 
&& 1.130000 0.000000 1.130000 ( 1.127514) 
if 0.950000 0.000000 0.950000 ( 0.956892) 
&& 1.120000 0.000000 1.120000 ( 1.124547) 
if 0.970000 0.000000 0.970000 ( 0.962618) 
&& 1.120000 0.000000 1.120000 ( 1.129094) 
if 0.960000 0.000000 0.960000 ( 0.954498) 
&& 1.120000 0.000000 1.120000 ( 1.125080) 
if 0.960000 0.000000 0.960000 ( 0.954001) 
&& 1.120000 0.000000 1.120000 ( 1.126329) 
if 0.950000 0.000000 0.950000 ( 0.953360) 
&& 1.130000 0.000000 1.130000 ( 1.122664) 
if 0.950000 0.000000 0.950000 ( 0.951391) 
&& 1.120000 0.010000 1.130000 ( 1.123455) 
if 0.980000 0.000000 0.980000 ( 0.977263) 
&& 1.120000 0.000000 1.120000 ( 1.126989) 
if 0.970000 0.000000 0.970000 ( 0.966264) 
&& 1.120000 0.000000 1.120000 ( 1.123184) 
if 0.960000 0.000000 0.960000 ( 0.956702) 
&& 1.120000 0.000000 1.120000 ( 1.124589) 
+0

ohh Tôi thấy Nếu là tốt hơn (mặc dù không đáng kể) – Ross

+0

Nó không đáng kể trong một chương trình một dòng, nhưng, thu nhỏ thành một chương trình đầy đủ tính năng làm rất nhiều điều kiện bên trong vòng nó có thể thêm đến phút hoặc lâu hơn. Lợi ích cho điểm chuẩn là chúng ta có thể học cách hiệu quả để làm mọi thứ, làm cho họ nhất quán, và vượt qua hiệu suất tốt nhất từ ​​những gì nhiều người coi là một ngôn ngữ "chậm". –

0

Tôi tin rằng cả hai phong cách của văn bản này sẽ có hiệu suất tương tự. Luôn luôn thích phiên bản đầu tiên vì nó dễ đọc hơn và mặc dù được coi là "hacky" và "hard-core" nhưng phiên bản thứ hai thực sự không có tối ưu hóa.

EDIT: Đây là cách thực hiện một số điểm chuẩn. Có vẻ như cả hai phiên bản thực sự thực hiện tương tự nhau:

limit = 10**7 
time_val=Time.now;sum=0;(0..limit).each{|t| even?(t) && sum += t};puts Time.now - time_val 

time_val=Time.now;sum=0;(0..limit).each{|t| sum += t if even?(t)};puts Time.now - time_val 
+0

Sử dụng [Benchmark] được tích hợp sẵn của Ruby (http://www.ruby-doc.org/stdlib-1.9.3/libdoc/benchmark/rdoc/Benchmark.html). Thật dễ dàng để thiết lập và cung cấp các cách phù hợp để định dạng đầu ra. –

6

Hiệu suất dường như không phải là vấn đề với tuyên bố đó.

Cách đầu tiên tốt hơn nhiều - dễ đọc hơn. Tương lai của bạn và những người khác sẽ làm việc trên mã sẽ cảm ơn bạn vì nó.

+0

Xem điểm chuẩn về sự khác biệt về tốc độ. –

+0

Đúng - không phải là vấn đề –

0

Chúng phải có cùng hiệu suất như chúng thực hiện tương tự hoặc ít nhất là sự khác biệt không đáng kể về hiệu suất.

+0

Bạn đã sai. 'true && 1 # => 1' –

+2

Chúng trả về các kết quả khác nhau ngay khi lần đầu tiên không phải là sự thật' 1 nếu sai # => nil' và 'false && 1 # => false' –

+0

Hmm thực sự vâng, xấu của tôi. Đó là kỳ lạ –

3

Bạn có thể sử dụng cả hai kiểu nhưng có một số khác biệt trong logic.

Được sử dụng trong một lời gọi phương thức:

def something 
    delete_article if user.owner? 
end 

sẽ trả lại bất cứ lợi nhuận delete_article phương pháp hoặc nil nếu người dùng không phải là chủ sở hữu.

Với:

def something 
    user.owner? && delete_article 
end 

nó sẽ quay trở lại false nếu người dùng không phải là một chủ sở hữu. Nếu người dùng là chủ sở hữu, nó sẽ trả về bất kỳ phương thức nào delete_article trả về.

Hiệu suất phải giống nhau.

+0

Trong cả hai trường hợp, giá trị trả lại sẽ đánh giá là "false" vì nil và false tương đương với "truthiness". –

+0

Đúng, nhưng bạn phải nhận biết loại giá trị mà bạn mong đợi ... có thể bạn có một cái gì đó như 'result.nil?'. Trong trường hợp 'false' là giá trị trả về, nó sẽ đánh giá thành' false'. – spas

0

Xét về hiệu suất, if là tốt hơn, như Tin Man lãm.Nhưng đôi khi, bạn cần phải viết bằng cách sử dụng && hoặc and nếu bạn muốn đặt nó thành một lớp lót, như trong trường hợp phần chính bao gồm biến không phải mẫu được xác định trong điều kiện:

do_something_with(foo) if foo = something_that_comes_from_condition 

sẽ trả về một lỗi, nhưng

(foo = something_that_comes_from_condition) && do_something_with(foo) 

hoặc

foo = something_that_comes_from_condition and do_something_with(foo) 

không có vấn đề như vậy.

Các vấn đề liên quan