0Pricing
Ruby Academy · Lekcja

Optymalizacja pamięci

Ograniczanie liczby alokacji

Optymalizacja pamięci to bezpłatna lekcja Ruby Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Ruby Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Ruby Academy zawiera 4 lekcji w sumie.

Dlaczego pamięć ma znaczenie

Każdy obiekt tworzony przez Ruby'ego zajmuje pamięć i zwiększa obciążenie garbage collection. Mniej alokacji oznacza szybsze i oszczędniejsze programy.

  • GC zatrzymuje program, aby odzyskać obiekty
  • Duża liczba alokacji powoduje częstsze uruchamianie GC
  • Ograniczenie liczby alokacji często przynosi największą poprawę
before = GC.stat(:total_allocated_objects)
100.times { 'new string' + '!' }
after = GC.stat(:total_allocated_objects)
puts "Allocated: #{after - before} objects"

Zliczanie alokacji

GC.stat udostępnia liczniki alokacji, które można porównać przed blokiem i po nim.

  • :total_allocated_objects stale rośnie
  • Odejmij wartość początkową od końcowej, aby zmierzyć wybrany fragment
def allocations
  before = GC.stat(:total_allocated_objects)
  yield
  GC.stat(:total_allocated_objects) - before
end

puts allocations { Array.new(1000) { |i| i.to_s } }

Zamrożone literały ciągów znaków

Każde powtórzenie literału ciągu znaków powoduje alokację nowego obiektu. Zamrożenie literałów pozwala Ruby ponownie wykorzystywać jedną niemutowalną instancję.

  • Należy dodać specjalny komentarz na początku pliku
  • Można też wywołać .freeze dla poszczególnych literałów
# frozen_string_literal: true

s1 = 'hello'
s2 = 'hello'
puts s1.equal?(s2)

Unikanie alokacji w pętlach

Tworzenie obiektów wewnątrz często wykonywanych pętli zwielokrotnia liczbę alokacji. Stałe należy przenieść poza pętlę.

  • Wyrażenia regularne, tablice i ciągi znaków należy tworzyć tylko raz
  • Należy ponownie wykorzystywać je podczas kolejnych iteracji
PATTERN = /\d+/

def count_numbers(lines)
  lines.count { |line| line.match?(PATTERN) }
end

puts count_numbers(['a1', 'bb', 'c3'])

Metody mutujące (bang)

Metody bez wykrzyknika zwracają nowe obiekty, natomiast metody z wykrzyknikiem mutują obiekt w miejscu, oszczędzając alokacje.

  • map!, gsub!, sort!
  • Należy ich używać tylko wtedy, gdy mutowanie oryginału jest bezpieczne
arr = [3, 1, 2]
arr.sort!
puts arr.inspect

s = 'hello world'
s.upcase!
puts s

Symbole a ciągi znaków jako klucze

Symbole są internowane: ten sam symbol jest jednym współdzielonym obiektem. Należy używać ich jako kluczy hashy.

  • Klucze będące ciągami znaków alokują za każdym razem nowy ciąg
  • Symbole oszczędzają pamięć przy wielokrotnym wyszukiwaniu
puts :name.equal?(:name)
puts 'name'.equal?('name')

Leniwe enumeratory

Łączenie metod map i select tworzy pośrednie tablice. lazy przetwarza elementy pojedynczo.

  • Nie są alokowane pośrednie kolekcje
  • To świetne rozwiązanie dla dużych lub nieskończonych sekwencji
result = (1..Float::INFINITY).lazy
  .select { |n| n.even? }
  .map { |n| n * n }
  .first(5)
puts result.inspect

Przetwarzanie strumieniowe zamiast wczytywania

Wczytywanie całego pliku do pamięci jest nieefektywne. Zamiast tego należy przetwarzać go strumieniowo, wiersz po wierszu.

  • each_line przetwarza jeden wiersz naraz
  • Zużycie pamięci pozostaje stałe niezależnie od rozmiaru pliku
text = "line1\nline2\nline3"
text.each_line do |line|
  puts line.strip.upcase
end

Konkatenacja ciągów znaków

Budowanie ciągów znaków za pomocą + w pętli alokuje za każdym razem nowy ciąg. Należy użyć <<, aby dopisywać w miejscu.

  • + tworzy nowy obiekt
  • << mutuje istniejący bufor
buffer = String.new
5.times { |i| buffer << "item#{i} " }
puts buffer

Pule obiektów i ponowne użycie

Należy ponownie wykorzystywać kosztowne obiekty zamiast tworzyć je od nowa.

  • Można buforować sparsowane konfiguracje lub skompilowane wyrażenia regularne
  • Należy użyć stałej lub wartości zapamiętywanej za pomocą memoizacji
def config
  @config ||= { host: 'localhost', port: 4567 }
end

puts config.equal?(config)

Uruchamianie GC w celu analizy

Można analizować działanie GC, aby potwierdzić poprawę.

  • GC.stat(:count) pokazuje, ile razy uruchomiono GC
  • Mniejsza liczba uruchomień po optymalizacji to dobry znak
start = GC.stat(:count)
50_000.times { |i| [i] }
puts "GC runs: #{GC.stat(:count) - start}"

Szybkie sprawdzenie

Sprawdźmy Państwa wiedzę na temat optymalizacji pamięci.

Podsumowanie

Poznali Państwo sposoby na optymalizację pamięci:

  • Liczenie alokacji za pomocą GC.stat
  • Zamrażanie literałów ciągów znaków i ponowne wykorzystywanie obiektów
  • Preferowanie metod z wykrzyknikiem oraz << w celu unikania nowych obiektów
  • Używanie symboli jako kluczy i leniwych enumeratorów w potokach
  • Przetwarzanie dużych ilości danych strumieniowo zamiast wczytywania ich w całości

W następnej części zajmą się Państwo typowymi wąskimi gardłami wydajności.

Często zadawane pytania

Czy lekcja „Optymalizacja pamięci” jest bezpłatna?

Tak — pełny tekst „Optymalizacja pamięci” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Ruby Academy, przejdź na CoddyKit PRO. Kurs Ruby Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Optymalizacja pamięci”?

Ograniczanie liczby alokacji Ćwiczysz Ruby Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Ruby Academy?

Nie wymagamy żadnego doświadczenia. Ruby Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Optymalizacja pamięci”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Ruby Academy?

Tak. Każda lekcja Ruby Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Pomiar wydajności
  2. Narzędzia do profilowania
  3. Optymalizacja pamięci
  4. Typowe wąskie gardła
← Powrót do Ruby Academy