Spis treściKliknij link, aby przejść do wybranego miejsca
Ta treść została automatycznie przetłumaczona z ukraińskiego.
Memoizacja (memoizacja) — to technika optymalizacji, która polega na cachowaniu wyników wykonania funkcji, aby uniknąć powtórnych obliczeń przy następnych wywołaniach. Jest to szczególnie przydatne dla kosztownych operacji (na przykład zapytań do bazy danych, skomplikowanych obliczeń lub pracy z API).
Dlaczego taka nazwa?
Termin "memoizacja" pochodzi od angielskiego słowa "memo" (notatka, przypomnienie) oraz łacińskiego rdzenia "memor-" (pamiętać). To sugeruje, że funkcja "zapamiętuje" (cachuje) swoje wyniki, aby uniknąć powtórnych obliczeń.
Po raz pierwszy termin ten użył Donald Michie, brytyjski naukowiec w dziedzinie sztucznej inteligencji, już w 1968 roku. Opisał technikę, w której obliczone wartości są przechowywane do dalszego wykorzystania.
Dlaczego nie po prostu "cachowanie"?
Memoizacja to specyficzny rodzaj cachowania.
- Memoizacja zazwyczaj cachuje wyniki funkcji na poziomie jednej instancji obiektu lub w ramach jednego procesu.
- Cachowanie ogólnie może obejmować przechowywanie w bazie danych, plikach, Redis, a nie tylko w zmiennych.
To znaczy cała memoizacja jest cachowaniem, ale nie każde cachowanie to memoizacja.
Jak działa memoizacja w Ruby?
W Ruby do memoizacji zazwyczaj używa się operatora ||= (lub jawnego przypisania wartości do zmiennej), aby przechować wynik w zmiennej i zwrócić go przy następnych wywołaniach.
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 # Wykona obliczenia i zapisze wartość
puts user.formatted_name # Użyje cachowanej wartości
W tym przypadku @formatted_name ||= name.upcase oznacza:
- Jeśli @formatted_name jeszcze nie jest ustawiony (nil lub false), otrzyma wartość name.upcase.
- W przeciwnym razie zwracana jest już zapisana wartość.
Uwaga dotycząca ||=
Operator ||= działa poprawnie, jeśli wartość może być nil lub false, ale jeśli oczekiwana wartość może być false, to taka memoizacja nie zadziała. Na przykład:
@result ||= false
Jeśli @result wynosi false, wyrażenie ponownie wykona obliczenia.
Aby zapewnić niezawodną memoizację, można użyć jawnego przypisania:
@result = some_expensive_operation if @result.nil?
Jak działa memoizacja w Rails?
W Ruby on Rails memoizacja jest używana do optymalizacji zapytań do bazy danych i innych kosztownych operacji. Przykład memoizacji w modelu:
class User < ApplicationRecord
def expensive_query
@expensive_query ||= some_heavy_calculation
end
private
def some_heavy_calculation
sleep(2) # Symulacja ciężkiej operacji
"Wynik obliczenia"
end
end
user = User.first
puts user.expensive_query # Czekamy 2 sekundy
puts user.expensive_query # Otrzymujemy cachowaną wartość
Memoizacja w before_action w kontrolerze:
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
To pomaga uniknąć powtórnych zapytań do bazy danych, jeśli metoda @user jest używana kilka razy w akcji.
Jakie są różnice między memoizacją a cachowaniem?
Krótko mówiąc:
Memoizacja – to przechowywanie wyniku w ramach jednego uruchomionego procesu (na przykład w zmiennej instancji obiektu).
Cachowanie – to szerszy termin, który może obejmować przechowywanie danych między procesami, w bazach danych, plikach, Redis, Memcached itp.
Ten post nie ma jeszcze żadnych dodatków od autora.