window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster już istnieje') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Jak zwiększyć wydajność Railsów - The Codest
The Codest
  • O nas
  • Nasze Usługi
    • Software Development
      • Frontend Development
      • Backend Development
    • Zespoły IT
      • Programiści frontendowi
      • Backend Dev
      • Inżynierowie danych
      • Inżynierowie rozwiązań chmurowych
      • Inżynierowie QA
      • Inne
    • Konsultacje IT
      • Audyt i doradztwo
  • Branże
    • Fintech i bankowość
    • E-commerce
    • Adtech
    • Healthtech
    • Produkcja
    • Logistyka
    • Motoryzacja
    • IOT
  • Wartość dla
    • CEO
    • CTO
    • Delivery Managera
  • Nasz zespół
  • Case Studies
  • Nasze Know How
    • Blog
    • Meetups
    • Webinary
    • Raporty
Kariera Skontaktuj się z nami
  • O nas
  • Nasze Usługi
    • Software Development
      • Frontend Development
      • Backend Development
    • Zespoły IT
      • Programiści frontendowi
      • Backend Dev
      • Inżynierowie danych
      • Inżynierowie rozwiązań chmurowych
      • Inżynierowie QA
      • Inne
    • Konsultacje IT
      • Audyt i doradztwo
  • Wartość dla
    • CEO
    • CTO
    • Delivery Managera
  • Nasz zespół
  • Case Studies
  • Nasze Know How
    • Blog
    • Meetups
    • Webinary
    • Raporty
Kariera Skontaktuj się z nami
Strzałka w tył WSTECZ
2022-02-17
Software Development

Jak zwiększyć wydajność Railsów

Konstanty Koszewski

Pomimo licznych zalet, Ruby on Rails jest nadal uważany za stosunkowo powolny framework webowy. Wszyscy wiemy, że Twitter porzucił Railsy na rzecz Scali. Jednak dzięki kilku sprytnym ulepszeniom możesz uruchomić swoją aplikację znacznie szybciej!

Ruby First

Ruby jest językiem silnie zorientowanym obiektowo. W rzeczywistości (prawie) wszystko w Ruby jest obiektem. Tworzenie niepotrzebnych obiektów może kosztować program wiele dodatkowej pamięci, więc należy tego unikać.

Aby zmierzyć różnicę, użyjemy memory_profiler oraz wbudowany moduł Benchmark do pomiaru wydajności czasowej. 

Używanie metod bang! na łańcuchach

require "memory_profiler"

report = MemoryProfiler.report do
data = "X" * 1024 * 1024 * 100
data = data.downcase
end

report.pretty_print

W poniższym zestawieniu utworzyliśmy ciąg znaków o rozmiarze 100 MB i zmniejszyliśmy każdy zawarty w nim znak. Nasz test porównawczy daje nam następujący raport:

Całkowita alokacja: 210765044 bajtów (6 obiektów)

Jeśli jednak zastąpimy linię 6 przez:

data.downcase!

Odczytywanie plików wiersz po wierszu

Przypuszczalnie musimy pobrać ogromną kolekcję danych zawierającą 2 miliony rekordów z pliku csv. Zazwyczaj wygląda to następująco:

require 'benchmark'

Benchmark.bm do |x|
x.report do
File.readlines("2mrecords.csv").map! {|line|line.split(",")}
end
end
użytkownik system całkowity rzeczywisty

12.797000 2.437000 15.234000 (106.319865)

Pełne pobranie pliku zajęło nam ponad 106 sekund. Całkiem sporo! Możemy jednak przyspieszyć ten proces, zastępując plik mapa! z prostą metodą podczas gdy pętla:

require 'benchmark'

Benchmark.bm do |x|
x.report do
file = file.open("2mrecords.csv", "r")
while line = file.gets
line.split(",")
end
end
end
użytkownik system całkowity rzeczywisty

6.078000 0.250000 6.328000 ( 6.649422)

Czas działania drastycznie się skrócił od czasu premiery mapa! metoda należy do określonej klasy, np. Hash#map lub Array#mapgdzie Ruby będzie przechowywać każdą linię przeanalizowanego pliku w pamięci tak długo, jak będzie wykonywana. Odśmiecacz Rubiego nie zwolni pamięci przed pełnym wykonaniem tych iteratorów. Jednak odczytanie go wiersz po wierszu spowoduje, że GC przeniesie pamięć z poprzednich wierszy, gdy nie będzie to konieczne.

Unikanie iteratorów metod na większych kolekcjach

Jest to rozszerzenie poprzedniego punktu o bardziej powszechny przykład. Jak już wspomniałem, Ruby iteratory są metodami obiektowymi i nie zwalniają pamięci, dopóki są wykonywane. W małej skali różnica jest bez znaczenia (a metody takie jak mapa wydaje się bardziej czytelna). Jednak w przypadku większych zestawów danych zawsze warto rozważyć zastąpienie go bardziej podstawowymi pętlami. Tak jak w poniższym przykładzie:

numberofelements = 10000000
randoms = Array.new(numberofelements) { rand(10) }

randoms.each do |line|
#do something
end

i po refaktoryzacji:

numberofelements = 10000000
randoms = Array.new(numberofelements) { rand(10) }

while randoms.count > 0
line = randoms.shift
#do something
end
"`

Użyj metody String::<<

Jest to szybka, ale szczególnie przydatna wskazówka. Jeśli dodasz jeden ciąg do drugiego za pomocą operatora += za kulisami. Ruby utworzy dodatkowy obiekt. Więc to: 

 a = "X"
 b = "Y"
 a += b

W rzeczywistości oznacza to:

 a = "X"
 b = "Y"
 c = a + b
 a = c

Operator mógłby tego uniknąć, oszczędzając trochę pamięci:

 a = "X"
 b = "Y"
 a << b

Porozmawiajmy o Railsach

The Framework Rails posiada mnóstwo "gotchas", które pozwoliłyby zoptymalizować kod szybko i bez dodatkowego wysiłku. 

Eager Loading AKA problem n+1 zapytań

Załóżmy, że mamy dwa powiązane modele, Post i Author:

class Autor < ApplicationRecord
has_many :posts
end

class Post < ApplicationRecord
belongs_to :author
end

Chcemy pobrać wszystkie posty w naszym kontrolerze i wyrenderować je w widoku wraz z ich autorami:

kontroler

def index
@posts = Post.all.limit(20)
end

widok

W kontrolerze, ActiveRecord utworzy tylko jedno zapytanie, aby znaleźć nasze posty. Ale później uruchomi również kolejne 20 zapytań, aby odpowiednio znaleźć każdego autora - zajmując dodatkowy czas! Na szczęście Railsy oferują szybkie rozwiązanie pozwalające połączyć te zapytania w jedno. Używając funkcji zawiera możemy przepisać nasz kontroler w ten sposób:

 def index
     @posts = Post.all.includes(:author).limit(20)
 end

Na razie tylko niezbędne dane będą pobierane w jednym zapytaniu. 

Można również użyć innych klejnotów, takich jak kula aby dostosować cały proces.

Dzwoń tylko do tego, czego potrzebujesz

Inną przydatną techniką zwiększania szybkości ActiveRecord jest wywoływanie tylko tych atrybutów, które są niezbędne do bieżących celów. Jest to szczególnie przydatne, gdy aplikacja zaczyna się rozrastać, a liczba kolumn w tabeli również wzrasta.

Weźmy nasz poprzedni kod jako przykład i załóżmy, że musimy tylko wybrać nazwiska z autorów. Możemy więc przepisać nasz kontroler:

 def index
     @posts = Post.all.includes(:author).select("name").limit(20)
 end

Teraz instruujemy nasz kontroler, aby pomijał wszystkie atrybuty z wyjątkiem tego, którego potrzebujemy.

Prawidłowe renderowanie częściowych

Załóżmy, że chcemy utworzyć osobną część dla naszych postów z poprzednich przykładów:


Na pierwszy rzut oka kod ten wygląda poprawnie. Jednak przy większej liczbie postów do wyrenderowania, cały proces będzie znacznie wolniejszy. Dzieje się tak, ponieważ Szyny ponownie wywołuje nasz partial z nową iteracją. Możemy to naprawić, używając funkcji kolekcje funkcja:

 .

Teraz, Szyny automatycznie ustali, który szablon powinien zostać użyty i zainicjuje go tylko raz.

Przetwarzanie w tle

Każdy proces, który jest bardziej czasochłonny i nie jest kluczowy dla bieżącego przepływu, może być uważany za dobrego kandydata do przetwarzania w tle, np. wysyłanie wiadomości e-mail, gromadzenie statystyk lub dostarczanie okresowych raportów. 

Sidekiq jest najczęściej używanym klejnotem do przetwarzania w tle. Używa Redis do przechowywania zadań. Pozwala również kontrolować przepływ procesów w tle, dzielić je na osobne kolejki i zarządzać wykorzystaniem pamięci dla każdego z nich.

Pisz mniej kodu, używaj więcej klejnotów

Szyny opracowała ogromną liczbę klejnotów, które nie tylko ułatwiają życie i przyspieszają proces rozwoju, ale także zwiększają szybkość działania aplikacji. Klejnoty takie jak Devise czy Pundit są zazwyczaj dobrze przetestowane pod względem szybkości i działają szybciej i bezpieczniej niż kod napisany na zamówienie w tym samym celu.

W przypadku jakichkolwiek pytań dotyczących poprawy Wydajność Railsówzasięg Inżynierowie The Codest aby skonsultować swoje wątpliwości.

Oferta dla programistów Ruby

Czytaj więcej:

Plusy i minusy tworzenia oprogramowania w Ruby

Szyny i inne środki transportu

Rails Development z TMUX, Vim, Fzf + Ripgrep

Powiązane artykuły

Software Development

Tworzenie przyszłościowych aplikacji internetowych: spostrzeżenia zespołu ekspertów The Codest

Odkryj, w jaki sposób The Codest wyróżnia się w tworzeniu skalowalnych, interaktywnych aplikacji internetowych przy użyciu najnowocześniejszych technologii, zapewniając płynne doświadczenia użytkowników na wszystkich platformach. Dowiedz się, w jaki sposób nasza wiedza napędza transformację cyfrową i biznes...

THEECODEST
Software Development

10 najlepszych firm tworzących oprogramowanie na Łotwie

Dowiedz się więcej o najlepszych łotewskich firmach programistycznych i ich innowacyjnych rozwiązaniach w naszym najnowszym artykule. Odkryj, w jaki sposób ci liderzy technologiczni mogą pomóc w rozwoju Twojej firmy.

thecodest
Rozwiązania dla przedsiębiorstw i scaleupów

Podstawy tworzenia oprogramowania Java: Przewodnik po skutecznym outsourcingu

Zapoznaj się z tym niezbędnym przewodnikiem na temat skutecznego tworzenia oprogramowania Java outsourcing, aby zwiększyć wydajność, uzyskać dostęp do wiedzy specjalistycznej i osiągnąć sukces projektu z The Codest.

thecodest
Software Development

Kompletny przewodnik po outsourcingu w Polsce

Wzrost liczby outsourcing w Polsce jest napędzany przez postęp gospodarczy, edukacyjny i technologiczny, sprzyjający rozwojowi IT i przyjazny klimat dla biznesu.

TheCodest
Rozwiązania dla przedsiębiorstw i scaleupów

Kompletny przewodnik po narzędziach i technikach audytu IT

Audyty IT zapewniają bezpieczne, wydajne i zgodne z przepisami systemy. Dowiedz się więcej o ich znaczeniu, czytając cały artykuł.

The Codest
Jakub Jakubowicz CTO & Współzałożyciel

Subskrybuj naszą bazę wiedzy i bądź na bieżąco!

    O nas

    The Codest - Międzynarodowa firma programistyczna z centrami technologicznymi w Polsce.

    Wielka Brytania - siedziba główna

    • Office 303B, 182-184 High Street North E6 2JA
      Londyn, Anglia

    Polska - lokalne centra technologiczne

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warszawa, Polska

      The Codest

    • Strona główna
    • O nas
    • Nasze Usługi
    • Case Studies
    • Nasze Know How
    • Kariera
    • Słownik

      Nasze Usługi

    • Konsultacje IT
    • Software Development
    • Backend Development
    • Frontend Development
    • Zespoły IT
    • Backend Dev
    • Inżynierowie rozwiązań chmurowych
    • Inżynierowie danych
    • Inne
    • Inżynierowie QA

      Raporty

    • Fakty i mity na temat współpracy z zewnętrznym partnerem programistycznym
    • Z USA do Europy: Dlaczego amerykańskie startupy decydują się na relokację do Europy?
    • Porównanie centrów rozwoju Tech Offshore: Tech Offshore Europa (Polska), ASEAN (Filipiny), Eurazja (Turcja)
    • Jakie są największe wyzwania CTO i CIO?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Warunki korzystania z witryny

    Copyright © 2025 by The Codest. Wszelkie prawa zastrzeżone.

    pl_PLPolish
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek pl_PLPolish