Skip to content

Instantly share code, notes, and snippets.

@julesce
Last active October 2, 2015 06:35
Show Gist options
  • Save julesce/1f5f3e6d20abf65eb7ef to your computer and use it in GitHub Desktop.
Save julesce/1f5f3e6d20abf65eb7ef to your computer and use it in GitHub Desktop.
try vs && vs if
# Summary
# -------
# If you care about performance, use `&&` or an `if` statement instead of the object.foo.try(:name) pattern.
#
# Like so...
# object.foo.name if object.foo
# OR
# object.foo && object.foo.name
class Object
def try(*a, &b)
if a.empty? && block_given?
yield self
else
public_send(*a, &b) if respond_to?(a.first)
end
end
end
class Foo
attr_reader :a
def initialize(a = nil)
@a = a
end
end
require "benchmark"
bar = Foo.new
baz = Foo.new(1)
n = 10000000
Benchmark.bm(40) do |x|
x.report("try"){ n.times { bar.a.try(:class).try(:to_s) } }
x.report("&& "){ n.times { baz.a && baz.a.class.to_s } }
x.report("if "){ n.times { baz.a.class.to_s if baz.a } }
end
# Results
# -------
# user system total real
# try 6.750000 0.000000 6.750000 ( 6.758586)
# && 2.300000 0.000000 2.300000 ( 2.297671)
# if 2.300000 0.000000 2.300000 ( 2.308800)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment