All original content is created in Ukrainian. Not all content has been translated yet. Some posts may only be available in Ukrainian.Learn more

What is Memoization (examples in Ruby and Ruby on Rails)?

Post cover: What is Memoization (examples in Ruby and Ruby on Rails)?
This content has been automatically translated from Ukrainian.
Memoization — is an optimization technique that involves caching the results of function executions to avoid repeated calculations on subsequent calls. This is especially useful for expensive operations (e.g., database queries, complex computations, or working with APIs).

Why this name?

The term "memoization" comes from the English word "memo" (note, reminder) and the Latin root "memor-" (to remember). This suggests that the function "remembers" (caches) its results to avoid repeated calculations.
This term was first used by Donald Michie, a British scientist in the field of artificial intelligence, back in 1968. He described the technique where computed values are stored for future use.

Why not just "caching"?

Memoization is a specific type of caching.
  • Memoization typically caches function results at the instance level of an object or within a single process.
  • Caching in general can include storage in databases, files, Redis, and not just in variables.
That is, all memoization is caching, but not all caching is memoization

How does Memoization work in Ruby?

In Ruby, memoization is typically done using the ||= operator (or explicitly storing the value in a variable) to keep the result in a variable and return it on subsequent calls.
class User
  attr_reader :name

  def initialize(name)
    @name = name
  end

  def formatted_name
    @formatted_name ||= name.upcase
  end
end

user = User.new("Marty")
puts user.formatted_name # Performs computation and stores the value
puts user.formatted_name # Uses the cached value
In this case, @formatted_name ||= name.upcase means:
  • If @formatted_name is not set yet (nil or false), it will get the value name.upcase.
  • Otherwise, the already stored value is returned.
Note about ||=
The ||= operator works correctly if the value can be nil or false, but if the expected value can be false, then such memoization will not work. For example:
@result ||= false
If @result is false, the expression will compute again.
For reliable memoization, explicit assignment can be used:
@result = some_expensive_operation if @result.nil?

How does Memoization work in Rails?

In Ruby on Rails, memoization is used to optimize database queries and other costly operations. Example of memoization in a model:
class User < ApplicationRecord
  def expensive_query
    @expensive_query ||= some_heavy_calculation
  end

  private

  def some_heavy_calculation
    sleep(2) # Simulating a heavy operation
    "Calculation result"
  end
end

user = User.first
puts user.expensive_query # Waits 2 seconds
puts user.expensive_query # Gets the cached value
Memoization in before_action in a controller:
class UsersController < ApplicationController
  before_action :set_user

  def show
    render json: { user: @user }
  end

  private

  def set_user
    @user ||= User.find(params[:id])
  end
end
This helps avoid repeated database queries if the @user method is used multiple times in the action.

What is the difference between memoization and caching?

In short:
Memoization is storing the result within a single running process (e.g., in an instance variable of an object).
Caching is a broader term that can include storing data between processes, in databases, files, Redis, Memcached, etc.

This post doesn't have any additions from the author yet.

What you need to know to build a successful freelance career in IT
23 Dec 16:03

What you need to know to build a successful freelance career in IT

meme code
meme code@memecode
Virtual cloud server: what it is and what makes it special
03 Jan 10:58

Virtual cloud server: what it is and what makes it special

meme code
meme code@memecode
[Fix] Heroku / SearchBox addon - indexing error "The client is unable to verify that the server is Elasticsearch"
31 Jan 13:09

[Fix] Heroku / SearchBox addon - indexing error "The client is unable to verify that the server is Elasticsearch"

meme code
meme code@memecode
06 Feb 15:31

Fix error [DEPRECATION] #adapters is deprecated. Use #profiles instead. (Codecov / docile)

meme code
meme code@memecode
What is a Promise in JavaScript and how to quickly understand its essence?
18 Feb 11:01

What is a Promise in JavaScript and how to quickly understand its essence?

meme code
meme code@memecode
The structure of Promise (JavaScript) and how to work with it
18 Feb 14:33

The structure of Promise (JavaScript) and how to work with it

meme code
meme code@memecode
What is debounce in JavaScript and why is it important?
21 Mar 16:39

What is debounce in JavaScript and why is it important?

meme code
meme code@memecode
What is CFB (Cipher Feedback)?
21 Mar 16:53

What is CFB (Cipher Feedback)?

meme code
meme code@memecode
What is XOR and how does it work?
21 Mar 17:05

What is XOR and how does it work?

meme code
meme code@memecode
Embedded programming: what it is and how to get started
24 Mar 16:48

Embedded programming: what it is and how to get started

meme code
meme code@memecode
Pessimistic Lock in Rails: what it is and when to use it. What are the alternatives?
31 Mar 17:45

Pessimistic Lock in Rails: what it is and when to use it. What are the alternatives?

meme code
meme code@memecode
Why does PostgreSQL skip IDs when saving new records? (Heroku)
31 Mar 19:13

Why does PostgreSQL skip IDs when saving new records? (Heroku)

meme code
meme code@memecode