如果条件vs&&,有任何性能提升

时间:2013-01-17 13:27:47

标签: ruby-on-rails ruby ruby-on-rails-3

如果用户是所有者,我有条件检查说删除和文章。

delete_article if user.owner?

另一种方式是

user.owner? && delete_article

选择其中任何一个是否有任何好处,或者它只是一种写作风格

6 个答案:

答案 0 :(得分:6)

性能不太可能成为该声明的问题。

第一个更好 - 它更容易阅读。你未来的自我和其他能够使用代码的人会感谢你。

答案 1 :(得分:3)

您可以使用这两种样式,但逻辑上存在一些差异。

用于方法调用:

def something
  delete_article if user.owner?
end
如果用户不是所有者,

将返回delete_article返回的方法或nil

使用:

def something
  user.owner? && delete_article
end

如果用户不是所有者,它将返回false。如果用户是所有者,则会返回delete_article返回的方法。

表现应该差不多。

答案 2 :(得分:2)

以下是测试if&&的速度的一些代码。

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)

答案 3 :(得分:0)

我相信这两种写作风格都会有相同的表现。总是喜欢第一个版本,因为它更容易阅读,虽然被认为是“hacky”和“hard-core”,但第二个版本实际上并没有优化。

编辑:这是如何做一些基准测试。似乎两个版本的表现确实相似:

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

答案 4 :(得分:0)

它们应具有与执行相同操作相同的性能,或至少可忽略不计的性能差异。

答案 5 :(得分:0)

就性能而言,if更好,正如Tin Man所展示的那样。但有时候,如果你想让它成为一个单行,你需要使用&&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)

没有这样的问题。