Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 无目标?vs.obj==零_Ruby_Null_Comparison - Fatal编程技术网

Ruby 无目标?vs.obj==零

Ruby 无目标?vs.obj==零,ruby,null,comparison,Ruby,Null,Comparison,使用obj.nil?或obj==nil更好吗?两者的好处是什么?就我个人而言,我更喜欢object.nil?,因为在较长的行中它可以减少混淆;但是,如果我在Rails中工作,我通常也会使用object.blank?,因为这也会检查变量是否为空。我发现自己根本没有使用.nil?,如果可以: unless obj // do work end 使用.nil?实际上速度较慢,但不明显.nil?只是一种检查对象是否等于nil的方法,除了视觉效果和所需的极少性能没有区别。可能建议使用.nil?比简单

使用
obj.nil?
obj==nil
更好吗?两者的好处是什么?

就我个人而言,我更喜欢
object.nil?
,因为在较长的行中它可以减少混淆;但是,如果我在Rails中工作,我通常也会使用
object.blank?
,因为这也会检查变量是否为空。

我发现自己根本没有使用
.nil?
,如果可以:

unless obj
  // do work
end
使用
.nil?
实际上速度较慢,但不明显
.nil?
只是一种检查对象是否等于nil的方法,除了视觉效果和所需的极少性能没有区别。

可能建议使用.nil?比简单的比较慢,仔细想想,这是有道理的

但如果规模和速度不是你关心的,那么。零?也许更具可读性

使用obj.nil是否更好?或obj==nil

完全一样。它具有完全相同的外部可观察效应(pfff)*

两者的好处是什么

如果您喜欢微优化所有对象将返回
false
.nil?
消息,但对象
nil
本身除外,而使用
=
消息的对象将执行微比较 使用另一个对象来确定它是否是同一个对象

*见评论

您可以在
nil?
上使用Symbol进行处理,但在
x==nil
上则不实用

arr = [1, 2, 3]
arr.any?(&:nil?) # Can be done
arr.any?{|x| x == nil} # More verbose, and I suspect is slower on Ruby 1.9.2
! arr.all? # Check if any values are nil or false
在许多情况下,这两种方法都不适用,只需测试布尔真值即可 虽然这两个操作非常不同,但我很确定它们总是会产生相同的结果,至少在某个边缘的人决定覆盖对象的
#nil?
方法之前是如此。(调用从对象继承或在
NilClass
中重写的
#nil?
方法,并与
nil
单例进行比较。)

我建议,当你有疑问时,你可以走第三条路,实际上,只是测试一个表达式的真值


因此,
如果x
而不是
如果x==nil
如果x.nil?
,以便在表达式值为false时进行此测试DTRT。这样做也有助于避免诱惑他人将
false类#nil?
定义为true。

撇开语法和样式不谈,我想看看测试nil的各种方法是如何“相同”的。因此,我编写了一些基准测试来查看,并对其进行了各种形式的零测试

TL;DR-结果优先 实际结果表明,在所有情况下,使用
obj
作为零检查是最快的
obj
始终比检查
obj.nil?
快30%或更多

令人惊讶的是,
obj
的执行速度大约是
obj==nil
上的变体的3-4倍,这似乎是一种惩罚性能的惩罚

想要将性能密集型算法的速度提高200%-300%吗?将所有
obj==nil
检查转换为
obj
。要对代码的性能进行沙袋处理吗?尽可能使用
obj==nil
。(只是开玩笑:不要对代码进行沙袋处理!)

归根结底,始终使用
obj
。这与规则不符:

基准条件 好的,这些就是结果。那么这个基准是如何组合起来的,进行了哪些测试,结果的细节是什么

我提出的零支票是:

  • obj
  • obj.nil?
  • !obj
  • !!obj
  • obj==nil
  • obj!=无
我选择了各种Ruby类型进行测试,以防结果根据类型发生变化。这些类型是
Fixnum
Float
false类
TrueClass
String
Regex

我在每种类型上都使用了这些nil检查条件,以查看它们之间在性能方面是否存在差异。对于每种类型,我都测试了nil对象和非nil值对象(例如
1_000_000
100_000.0
false
true
“string”
,以及
/\w//code>),以查看在一个为零的对象上检查nil与在一个非为零的对象上检查nil是否有区别

基准 排除了所有这些,下面是基准代码:

需要“基准测试”
nil_obj=nil
N=10_000_000
把你的描述
[1_000_000,100_000.0,false,true,“string”,/\w/]。每个都有| obj|
title=“#{obj}(#{obj.class.name})”
放入“=================================================================================================================================================================================================================================================================================================================================
放置“为obj=#{title}运行测试”
Benchmark.bm(15,title)do|x|
隐式_obj_report=x.report(“obj:”){N.times{obj}
隐式报告=x.report(“nil_obj:”){N次{nil_obj}
explicit_obj_report=x.report(“obj.nil:”){N.times{obj.nil?}
explicit_nil_report=x.report(“nil_obj.nil:”){N.times{nil_obj.nil?}
not_obj_report=x.report(“!obj:”){N次{!obj}
not_nil_report=x.report(“!nil_obj:”){N次{!nil_obj}
not_not_obj_report=x.report(!!obj:){N.times{!!obj}
not_not_nil_report=x.report(!!nil_obj:){N次{!!nil_obj}
equals_obj_report=x.report(“obj==nil:”){N次{obj==nil}
等于{nil_report=x.report(“nil_obj==nil:”){N次{nil_obj==nil}}
not_等于_obj_report=x.report(“obj!=nil:”){N次{obj!=nil}
not_等于_nil_report=x.report(“nil_obj!=nil:”){N次{nil_obj!=nil}}
结束
结束
结果 结果很有趣,因为Fixnum、Float和String类型的性能实际上是i