DEV Community

Andy Huynh
Andy Huynh

Posted on • Updated on

 

memoization

You've seen it before: ||=.

This is Ruby's way of caching data. Take the contrived example below that involves zero caching.

class Account
  ...

  private

  def retrieve_credit_card
    if purchasing_account.present?
      purchasing_account.credit_card
    end
  end

  def purchasing_account
    Account.find(id)
  end
end
Enter fullscreen mode Exit fullscreen mode

Here's why this sucks: we hit the database twice. When invoking #retrieve_credit_card, we ask for the account twice. This gets expensive on the database and a bad thing working in larger codebases with lots of data.

Cache the Account#find query like so.

class Account
  def retrieve_credit_card
    if purchasing_account.present?
      purchasing_account.credit_card
    end
  end

  private

  def purchasing_account
    @purchasing_account ||= Account.find(id)
  end
end
Enter fullscreen mode Exit fullscreen mode

This implementation is more efficient. When asking if a purchasing_account is present.. that's the first hit to the database. However, this time we ask that same instance (our cached version) for the its credit card. This saves us a roundtrip to the database. Optimization for the win!

Also, this is an actual example of a commit by yours truly. I was digging through my old pull requests and discovered I wrote this commit at work. Embarrassing to say the least, but it's fun to point fingers at your younger, simple minded self. Get cachin', ya'll.

Top comments (0)

An Animated Guide to Node.js Event Loop

Node.js doesn’t stop from running other operations because of Libuv, a C++ library responsible for the event loop and asynchronously handling tasks such as network requests, DNS resolution, file system operations, data encryption, etc.

What happens under the hood when Node.js works on tasks such as database queries? We will explore it by following this piece of code step by step.