ユーザーが所有者である場合、削除と記事を確認する条件があります。
delete_article if user.owner?
別の方法は
user.owner? && delete_article
どちらかを選択する利点はありますか、それとも単なる書き方ですか
ユーザーが所有者である場合、削除と記事を確認する条件があります。
delete_article if user.owner?
別の方法は
user.owner? && delete_article
どちらかを選択する利点はありますか、それとも単なる書き方ですか
そのステートメントでは、パフォーマンスが問題になることはほとんどありません。
最初のものははるかに優れており、読みやすくなっています。あなたの将来の自分やコードに取り掛かる人は、あなたに感謝するでしょう。
両方のスタイルを使用できますが、ロジックにいくつかの違いがあります。
メソッド呼び出しで使用:
def something
delete_article if user.owner?
end
メソッド delete_article が返すもの、またはnil
ユーザーが所有者でない場合は何でも返します。
と:
def something
user.owner? && delete_article
end
false
ユーザーが所有者でない場合は返されます。ユーザーが所有者の場合、メソッド delete_article が返すものは何でも返します。
パフォーマンスはほぼ同じはずです。
if
vsの速度をテストするコードを次に示し&&
ます。
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
そして出力:
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)
これを書く両方のスタイルは同じパフォーマンスを発揮すると思います。最初のバージョンの方が読みやすいため、常に優先してください。「ハッキー」で「ハードコア」と見なされますが、2 番目のバージョンは実際には最適化されていません。
編集:ベンチマークを行う方法は次のとおりです。両方のバージョンが実際に同様に機能するようです。
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
同じことを行うのと同じパフォーマンスを発揮するか、少なくともパフォーマンスの違いはごくわずかである必要があります。
if
ティンマンが示すように、パフォーマンスの面では優れています。ただし、メイン部分に条件で定義される非インスタンス変数が含まれている場合のように、ワンライナーにしたい場合は、using &&
orを記述する必要がある場合があります。and
do_something_with(foo) if foo = something_that_comes_from_condition
エラーを返しますが、
(foo = something_that_comes_from_condition) && do_something_with(foo)
また
foo = something_that_comes_from_condition and do_something_with(foo)
はそのような問題はありません。