Ruby:无目标’案例’,与’if’相比

前端之家收集整理的这篇文章主要介绍了Ruby:无目标’案例’,与’if’相比前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
(我已经问了这个问题 at Ruby Forum,但它没有得出任何答案,所以我现在正在改编)

根据我的理解,以下几段代码是等效的
Ruby 1.9及更高版本:

# (1)
case
when x < y
  foo
when a > b
  bar
else
  baz
end

# (2)
if x < y
  foo
elsif a > b
  bar
else
  baz
end

到目前为止,我总是习惯于使用(2).有人会想
特殊原因,为什么(1)或(2)是“更好”,或者只是
品味问题?

澄清:一些用户反对,这个问题只是“基于意见”,因此不适合这个论坛.因此,我认为我没有说清楚自己:我不想开始讨论个人编程风格.我提出这个话题的原因是:

令我感到惊讶的是,Ruby提供了两种非常不同的语法(无目标情况和if-elsif),因为在我看来,它的目的完全相同,特别是因为if-elsif语法实际上是每个程序员都是熟悉.我甚至不会将’target-less if’视为“语法糖”,因为它不允许我比’if-elsif’更明确地表达编程逻辑.

所以我想知道在什么情况下我可能想要使用’无目标案例’构造.它是否具有性能优势?它是否与if-elsif有些微妙的区别,我才注意到它?

关于实施无目标案件的其他调查结果:

Olivier Poulin指出,一个无目标的case语句会明确地使用===运算符来反对值“true”,与’if’相比,这会导致’case’的(微小的)性能惩罚(和更多的原因,我不明白为什么有人可能想要使用它).

但是,在检查Ruby 1.9和Ruby 2.0的case语句的文档时,我发现它们对它的描述不同,但至少都表明在这种情况下可能不会使用===.在Ruby 1.9的情况下:

Case statements consist of an optional condition,which is in the position of an argument to case,and zero or more when clauses. The first when clause to match the condition (or to evaluate to Boolean truth,if the condition is null) “wins”

这里说,如果条件(即’case’之后的条件)为空(即不存在),则计算为true的第一个’when’子句是正在执行的子句.这里没有提到===.

Ruby 2.0,措辞完全不同:

The case expression can be used in two ways. The most common way is to compare an object against multiple patterns. The patterns are matched using the +===+ method […..]. The other way to use a case expression is like an if-elsif expression: [example of target-less case is given here].

因此,它表示===以“第一”方式使用(具有目标的情况),而无目标情况“就像”if-elsif.这里没有提到===.

解决方法

Midwire ran a few benchmarks and concluded that if/elsif is faster
than case because case “implicitly compares using the more expensive
=== operator”.

Here是我得到这个报价的地方.它将if / elsif语句与case进行比较.

它是非常彻底的,并探讨了指令序列的差异,肯定会让你知道哪个更好.

我从帖子中提取的主要内容是if / else if和case没有巨大差异,两者通常可以互换使用.

根据您拥有的案例数量,可能会出现一些主要差异.

n = 1 (last clause matches)
if:           7.4821e-07
threequal_if: 1.6830500000000001e-06
case:         3.9176999999999997e-07

n = 15 (first clause matches)
if:           3.7357000000000003e-07
threequal_if: 5.0263e-07
case:         4.3348e-07

正如您所看到的,如果最后一个子句匹配,如果/ elsif运行比case慢得多,而如果第一个子句匹配,则反过来.

这种差异来自if / elsif使用branchunless,而case在其指令序列中使用branchif的事实.

这是我自己做的一个测试,使用无目标案例和if / elsif语句(使用“==”).第一次是案例,而第二次是if / elsif.

第一个测试,5个语句,5个if / elsif,第一个子句对两个都是真的.

Time elapsed 0.052023 milliseconds                                                                                                                                                                                                                                                                                                                                                                                                       
Time elapsed 0.031467999999999996 milliseconds

第二次测试,5次语句,5次/ elsif,最后一次(第5次)子句对两者都是真的.

Time elapsed 0.001224 milliseconds                                                                                                                                                                                                                                                                                                                                                                                                 
Time elapsed 0.028578 milliseconds

正如您所看到的,正如我们之前看到的那样,当第一个子句为真时,如果/ elsif的性能优于case,而case在最后一个子句为真时具有巨大的性能优势.

结论

运行更多测试表明它可能归结为概率.如果您认为答案将在您的子句列表中提前出现,请使用if / elsif,否则情况似乎更快.

显示的主要事实是,case和if / elsif都同样有效,并且使用一个而不是另一个归结为概率和品味.

猜你在找的Ruby相关文章