fast-ruby icon indicating copy to clipboard operation
fast-ruby copied to clipboard

Benchmark presence check

Open TheSmartnik opened this issue 9 years ago • 4 comments

I've been wondering whether the new safe method navigation syntax is fast. Turned out it's almost as fast as simple method invocation.

TheSmartnik avatar Jun 19 '16 12:06 TheSmartnik

You are testing happy path, where calling method itself is really fastest way (no surprises here). What sad man operator actually gives is that you avoid chains like o && o.foo && o.foo.bar. That provides you with:

a) slimmer and cleaner code a&.foo&.bar b) handles situation when middle call (#foo in the above) returns nil c) memoizes middle calls

by c i mean, that a&.foo&.bar is actually a shorthand syntax for:

(_x = a) && (_x = _x.foo) && _x.bar

Now, imagine following, you have Book class and User that can borrow it in Library. Obviously in this case Book might be or might not be borrowed by user:

class Book
  # @return [User, nil]
  def borrower
    # ...
  end

Now here's example where &. comes into play:

if book&.borrower&.student?
  # ...
else
  # book is either NOT borrowed or borrower user is not student
end

Obviously example is pretty stupid, but still demonstrates WHY &. is needed and WHY it's invalid to compare it to simple method invocation. When nil in the middle of chain is an exception - then you MUST use simple method invocation. When middle call evaluation MIGHT return nil as a valid response you should use &.. All simple :D

So, in other words the only comparison that makes sens here is:

a &. b &. c

# vs

a && a.b && a.c

# vs

a.try!(:b).try!(:c)

Notice that &. acts like Rails' #try! not #try. It will raise NoMethodError if intermediate object is not nil and does not respond to given method.

ixti avatar Jun 20 '16 14:06 ixti

@ixti simple method calling is present in this benchmark just to showcase how fast safe navigation operator is. Maybe I should've make it more clear by adding note to readme instead of adding it to benchmark.

Notice that &. acts like Rails' #try!

Thanks, didn't know that

TheSmartnik avatar Jun 20 '16 18:06 TheSmartnik

Maybe I should've make it more clear by adding note to readme instead of adding it to benchmark.

Yeah. It's better to add that safe navigation with happy path is nearly as fast as simple calls chain.

ixti avatar Jun 20 '16 19:06 ixti

@ixti thanks for your feedback. Fixed.

TheSmartnik avatar Jun 20 '16 22:06 TheSmartnik

Closing this until someone addresses the issues that were mentioned in this PR.

etagwerker avatar Jun 17 '23 01:06 etagwerker